<?php
/*
 * shopping/order/settlement/MethodZeusSLCard.class.php
 * 
 * CopyRight(C) 2010 Shopformer Development Team. All Right Reserved
 * URL: http://sourceforge.jp/projects/shopformer/
 * 
 * 
 * Mail: m_nakashima@users.sourceforge.jp
 * Auther: Masanori Nakashima
 * Last Update: 2010-06-18
 */
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'MethodBase.class.php');
require_once(dirname(dirname(dirname(dirname(__FILE__)))).DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'HttpRequest.class.php');
/**
 * shopping_order_settlement_MethodZeusSLCard
 * 決済プラグイン:株式会社ゼウス決済代行 Secure Link方式 クレジットカード決済クラス
 * 
 * 株式会社ゼウスが提供する決済代行のクレジットカード決済用のshopping_order_settlement_MethodBaseの実装クラスです。
 * http://www.cardservice.co.jp/
 * 注文が完了した場合にエラーがなければで注文状態を「新規」、決済状態を「決済済」に設定します。
 * エラーが発生していた場合は注文状態を「無効」、決済状態を「決済エラー」に設定します。
 * 
 */
class shopping_order_settlement_MethodZeusSLCard extends shopping_order_settlement_MethodBase {
	/**
	 * コンストラクタ
	 */
	function shopping_order_settlement_MethodZeusSLCard() {
		$this->viewName			= 'クレジットカード';
		$this->enable			= false;
		$this->statusSettle		= 101;
		$this->settingValues	= array(
			'client_ip'		=> '',
			// オーダー情報送信先URL
			'order_url'		=> 'https://linkpt.cardservice.co.jp/cgi-bin/secure.cgi',
			// オーダー情報送信先URL
			'credit_dev'		=> 'VISA,MASTER,JCB,DINERS,AMEX',
		);
		$this->settingLabels	= array(
			'client_ip'		=> 'クライアントIPコード',
			'order_url'		=> 'オーダー情報送信先URL',
			'credit_dev'		=> '分割払い可能カードブランド',
		);
		$this->feeType			= 0;
		$this->feeValue			= 0;
		$this->mailTemplateName	= 'thanks';
		$this->mailComment	= "クレジットカードにてお支払いが完了しています。";
		$this->mailOrder	= "クレジットカードにてお支払いが完了しています。\n";
		$this->cardDivHash	= array('01'=>'一括','03'=>'3回','05'=>'5回','06'=>'6回','10'=>'10回','12'=>'12回','15'=>'15回','18'=>'18回','20'=>'20回','24'=>'24回','99'=>'リボ');
		$this->explanation	= <<< __METHOD_EXPLANATION__
<div>
株式会社ゼウスのクレジットカード決済代行を利用したお支払いです。<br />
ご入力頂いたカード情報は直接株式会社ゼウスに送信いたします。当方ではカード情報は一切保持いたしません。<br />
</div>
__METHOD_EXPLANATION__;

		$this->attention	= <<< __METHOD_EXPLANATION__
<div>カード決済を実行します</div>
__METHOD_EXPLANATION__;
	}
	/**
	 * 決済方法名を取得
	 */
	function getMethodName() {
		return '株式会社ゼウス:クレジットカード決済プラグイン Secure Link方式';
	}
	/**
	 * 決済方法固有の番号を取得します。
	 */
	function getMethodNumber() {
		return '26';
	}
	/**
	 * Complete画面が必要か確認します
	 * @return true/false
	 */
	function needComplete(){
		return true;
	}
	/**
	 * 必要に応じた入力フォームHTML取得メソッド
	 */
	function getInputFormHtml( & $request, & $shoppingOrderObject ) {
		$zeusCardNumber		= $shoppingOrderObject->zeuscardnumber;
		$zeusCardName		= $shoppingOrderObject->zeuscardname;
		$errorMessage		= '';
		$formNumColor			= '#fff0ff';
		if( is_array($shoppingOrderObject->columnErrorHash['settle_method_errors']) && count($shoppingOrderObject->columnErrorHash['settle_method_errors'])>0 ) {
			foreach($shoppingOrderObject->columnErrorHash['settle_method_errors'] as $msg) {
				$errorMessage	.= '<span style="font-size:x-small;color:#ff0000;">'.$msg.'</span><br />';
			}
			$formNumColor	= '#fff0f0';
		}
		$returnString		= <<< __HTML_INPUTFORM__
カード番号とカード名義を入力してください。<br />
▼カード番号 <span style="font-size:x-small;color:#800000;">※選択した場合必須 ハイフンなしの半角数字で入力してください</span><br />
<input type="text" name="zeuscardnumber" size="30" value="${zeusCardNumber}" style="background-color:${formNumColor};" /><br />
▼カード名義 <span style="font-size:x-small;color:#800000;">※選択した場合必須<br />カードに記載の通り入力してください 例) TARO SHOP</span><br />
<input type="text" name="zeuscardname" size="40" value="${zeusCardName}" style="background-color:${formNumColor};" /><br />
▼カード有効期限 <span style="font-size:x-small;color:#800000;">※選択した場合必須</span><br />
<select name="zeuslimitmonth" style="background-color:${formNumColor};">
	<option value="" style="background-color:${formNumColor};">月</option>
__HTML_INPUTFORM__;
		for( $i=1; $i<=12; $i++ ) {
			$returnString	.= '<option value="'.sprintf('%02d',$i).'"';
			if( $shoppingOrderObject->zeuslimitmonth == sprintf('%02d',$i) ) {
				$returnString	.= ' selected';
			}
			$returnString	.= ' style="background-color:'.$formNumColor.';">'.sprintf('%02d',$i).'</option>';
		}
		$returnString	.= '</select>/<select name="zeuslimityear" style="background-color:'.$formNumColor.';">';
		$returnString	.= '<option value="" style="background-color:'.$formNumColor.';">年</option>';
		for( $i=date('y');$i<date('y')+10;$i++ ) {
			$returnString	.= '<option value="'.sprintf('%02d',$i).'"';
			if( $shoppingOrderObject->zeuslimityear == sprintf('%02d',$i) ) {
				$returnString	.= ' selected';
			}
			$returnString	.= ' style="background-color:'.$formNumColor.';">'.sprintf('%02d',$i).'</option>';
		}
		$returnString	.= '</select><br />';
		// 分割払い対応カードブランド
		$cardDivTypeArray	= explode(',',$this->settingValues['credit_dev']);
		$cardTypeArray		= array('VISA','MASTER','JCB','DINERS','AMEX');
		if( strlen(trim($this->settingValues['credit_dev'])) > 0  && count($cardDivTypeArray) > 0 ) {
			$returnString	.= '▼カード種類 <br /><select name="zeuscardtype" style="background-color:'.$formNumColor.';" onchange="">'
				.'<option value="" style="background-color:'.$formNumColor.';color:#800000;">必須</option>';
			$noneDivCardArray	= array();
			foreach( $cardTypeArray as $cardType ) {
				$returnString	.= '<option value="'.$cardType.'" style="background-color:'.$formNumColor.';"';
				if( $shoppingOrderObject->zeuscardtype == $cardType ) {
					$returnString	.= ' selected';
				}
				$returnString	.= '>'.$cardType.'</option>';
				if( !in_array($cardType,$cardDivTypeArray) ) {
					array_push( $noneDivCardArray, $cardType );
				}
			}
			$returnString	.= '</select><br />';
			$returnString	.= '▼お支払方法 <br /><select name="zeuscarddiv" id="zeuscarddiv" style="background-color:'.$formNumColor.';" onchange="">';
			foreach( $this->cardDivHash as $divVal => $divName ) {
				$returnString	.= '<option value="'.$divVal.'" style="background-color:'.$formNumColor.';"';
				if( $shoppingOrderObject->zeuscarddiv == $divVal ) {
					$returnString	.= ' selected';
				}
				$returnString	.= '>'.$divName.'</option>';
			}
			$returnString	.= '</select><br />';
			if( count($noneDivCardArray) > 0 ) {
				$returnString	.= '<span style="font-size:x-small;color:#800000;">※'.implode(',',$noneDivCardArray).'は分割・リボをご利用いただけません。</span><br />';
			}
			if( in_array('DINERS',$cardDivTypeArray) ) {
				$returnString	.= '<span style="font-size:x-small;color:#800000;">※DINERSの方は[一括]または[リボ]のみご利用いただけます。</span><br />';
			}
			if( in_array('AMEX',$cardDivTypeArray) ) {
				$returnString	.= '<span style="font-size:x-small;color:#800000;">※AMEXの方は[一括]のみご利用いただけます。</span><br />';
			}
		}
		$returnString	.= $errorMessage;
		return $returnString;
	}
	/**
	 * confirm時の処理
	 */
	function confirm( & $request, & $shoppingOrderObject ) {
		// 入力フォームの内容を取得してショッピングオーダーオブジェクトに設定する
		$shoppingOrderObject->zeuscardnumber	= mb_convert_kana(trim(stripslashes($_POST['zeuscardnumber'])),'a');
		$shoppingOrderObject->zeuscardnumber	= str_replace('-','',$shoppingOrderObject->zeuscardnumber);
		$shoppingOrderObject->zeuscardnumber	= str_replace('　','',$shoppingOrderObject->zeuscardnumber);
		$shoppingOrderObject->zeuscardname		= mb_convert_kana(trim(stripslashes($_POST['zeuscardname'])),'a');
		$shoppingOrderObject->zeuscardname		= str_replace('　','',$shoppingOrderObject->zeuscardname);
		$shoppingOrderObject->zeuslimityear		= mb_convert_kana(trim(stripslashes($_POST['zeuslimityear'])),'a');
		$shoppingOrderObject->zeuslimitmonth	= mb_convert_kana(trim(stripslashes($_POST['zeuslimitmonth'])),'a');
		$shoppingOrderObject->zeuscardtype		= mb_convert_kana(trim(stripslashes($_POST['zeuscardtype'])),'a');
		$shoppingOrderObject->zeuscarddiv		= mb_convert_kana(trim(stripslashes($_POST['zeuscarddiv'])),'a');
		// 妥当性検査
		if( strlen($shoppingOrderObject->zeuscardnumber) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカード番号を入力してください。');
		} else if( preg_match('/^[0-9]{16}$/',$shoppingOrderObject->zeuscardnumber) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカード番号は16ケタの数字で入力してください。');
		}
		if( strlen($shoppingOrderObject->zeuscardname) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカードに記載されている名義を入力してください。');
		}
		if( strlen($shoppingOrderObject->zeuslimityear) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカード期限年を選択してください。');
		} else if( preg_match('/^[0-9]{2}$/',$shoppingOrderObject->zeuslimityear) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカード期限年は2ケタの数字で入力してください。');
		}
		if( strlen($shoppingOrderObject->zeuslimitmonth) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカード期限月を選択してください。');
		} else if( preg_match('/^[0-9]{2}$/',$shoppingOrderObject->zeuslimitmonth) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','クレジットカード期限月は2ケタの数字で入力してください。');
		}
		// 分割払い入力
		$cardDivTypeArray	= explode(',',$this->settingValues['credit_dev']);
		$cardTypeArray		= array('VISA','MASTER','JCB','DINERS','AMEX');
		if( strlen(trim($this->settingValues['credit_dev'])) > 0  && count($cardDivTypeArray) > 0 ){
			if( strlen($shoppingOrderObject->zeuscardtype) == 0 ) {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','カード種類を選択してください。');
			} else if( !in_array($shoppingOrderObject->zeuscardtype,$cardTypeArray) ) {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','カード種類を正しく選択してください。');
			} else if( !in_array($shoppingOrderObject->zeuscardtype,$cardDivTypeArray) && '01' != $shoppingOrderObject->zeuscarddiv ) {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','申し訳ございませんが'.$shoppingOrderObject->zeuscardtype.'カードでは分割払いをご利用いただけません。');
			} else if( 'AMEX' == $shoppingOrderObject->zeuscardtype && '01' != $shoppingOrderObject->zeuscarddiv ) {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','申し訳ございませんがAMEXの分割払いには対応しておりません。');
			} else if( 'DINERS' == $shoppingOrderObject->zeuscardtype
				&& '01' != $shoppingOrderObject->zeuscarddiv && '99' != $shoppingOrderObject->zeuscarddiv ) {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','申し訳ございませんがDINERSは[一括]と[リボ]払いのみの対応となっております。');
			}
		}
	}
	/**
	 * execute時の処理
	 */
	function execute( & $request, & $shoppingOrderObject ) {
		// HttpRequestクラス
		$httpRequest	= new util_HttpRequest($this->settingValues['order_url'],'post');
		// 基本情報設定
		$httpRequest->addPostData('clientip', $this->settingValues['client_ip']);
		$httpRequest->addPostData('cardnumber', $shoppingOrderObject->zeuscardnumber);
		$httpRequest->addPostData('username', $shoppingOrderObject->zeuscardname);
		// カード期限年月
		$httpRequest->addPostData('expyy', $shoppingOrderObject->zeuslimityear );
		$httpRequest->addPostData('expmm', $shoppingOrderObject->zeuslimitmonth );
		// 決済通貨の指定（暫定：固定円）
		$httpRequest->addPostData('send', 'mall');

		// 注文固有情報設定
		$memberObject	= $shoppingOrderObject->memberObject;
		$email			= null;
		if( strlen($memberObject->pc_mail) > 0 ) {
			$email	= $memberObject->pc_mail;
		} else if( strlen($memberObject->mb_mail) > 0 ) {
			$email	= $memberObject->mb_mail;
		}
		$httpRequest->addPostData('sendid', $shoppingOrderObject->order_id);
		$httpRequest->addPostData('telno', str_replace('-','',$shoppingOrderObject->memberObject->telephone_number));
		$httpRequest->addPostData('email', $email);
		// 決済金額
		$httpRequest->addPostData('money', $shoppingOrderObject->payment_total);
		
		// レスポンス時にゼウス側のオーダー番号を取得する
		$httpRequest->addPostData('printord', 'yes');
//		// レスポンスのみを取得しCGIコールを無にする
//		$httpRequest->addPostData('pubsec', 'yes');

		// 分割払いが可能の場合
		$cardDivTypeArray	= explode(',',$this->settingValues['credit_dev']);
		if( count($cardDivTypeArray) > 0 ){
			$shoppingOrderObject->settle_log	.= 'zeusecarddiv='.$shoppingOrderObject->zeuscarddiv."\r\n\r\n";
			$httpRequest->addPostData('div', $shoppingOrderObject->zeuscarddiv);
		}
		// HTTPリクエスト実行
		if( $httpRequest->send(null,60) ) {
			// 応答内容の解析
			$responseCode	= $httpRequest->statusCode;
			$responseBody	= trim($httpRequest->responseBody);
			$responseBody	= str_replace("\r\n","\n",$responseBody);
			$responseBody	= str_replace("\r","\n",$responseBody);
			// 結果
			if( preg_match('/Success\\_order/',$responseBody) > 0 ) {
				// 決済正常終了
				$paramArray	= explode("\n",$responseBody);
				foreach( $paramArray as $line ) {
					$line	= trim($line);
					if( strlen($line) > 0 && $line != 'Success_order' ) {
						$shoppingOrderObject->setSettleTransactionCode( $request, $line );
						break;
					}
				}
			} else {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','決済が失敗しました。ご利用カード、または入力内容をご確認ください。ご不明な点はカスタマーサポートセンターにお問い合わせください。');
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','カスタマーサポートセンター');
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','電話番号：0570-02-3939 / E-mail：support@cardservice.co.jp');
			}
		} else {
			// リクエストエラー
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','決済サーバーが正常な応答を返しませんでした。ご利用カード、または入力内容をご確認ください。ご不明な点はカスタマーサポートセンターにお問い合わせください。');
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','カスタマーサポートセンター');
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','電話番号：0570-02-3939 / E-mail：support@cardservice.co.jp');
		}
		// 結果を格納した注文情報を更新
		$logMessage	= date('Y-m-d H:i:s')."\r\n";
		$dbo		= $request->getAttribute('dbo');
		if( $request->isError() ) {
			$logMessage	.= 'SETTLE=NG'."\r\n".implode("\n",$request->errors);
		} else {
			$logMessage	.= 'SETTLE=OK';
			$shoppingOrderObject->setSettleDate( $request, $shoppingOrderObject->settle_date );
		}
		$logMessage	.= "\r\n\r\n".$responseBody;
		$shoppingOrderObject->settleLogLn( $request, $logMessage );
		if( $request->isError() ) {
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * complete時にパラメータから判断して指定の注文オブジェクトを作成します。
	 */
	function getCompleteShoppingObject( & $request ) {
		// アクセス制御
		if( $_SERVER['REMOTE_ADDR'] != '210.164.6.67'
			&& $_SERVER['REMOTE_ADDR'] != '202.221.139.50' ) {
			// アクセス元がゼウスカード決済サーバでない場合は処理しない
			return null;
		}
		$dbo		= $request->getAttribute('dbo');
		// GETパラメータを取得
		$result		= trim(stripslashes($_GET['result']));
		$clientip	= trim(stripslashes($_GET['clientip']));
		$ordd		= trim(stripslashes($_GET['ordd']));
		$money		= trim(stripslashes($_GET['money']));
		$telno		= trim(stripslashes($_GET['telno']));
		$email		= trim(stripslashes($_GET['email']));
		$sendid		= trim(stripslashes($_GET['sendid']));
		$sendpoint	= trim(stripslashes($_GET['sendpoint']));
		// 注文情報読み込みの試行
		if( strlen($sendid) > 0 ) {
			$shoppingOrderObject	= new shopping_DaoShoppingOrder();
			if( $dbo->loadById( $shoppingOrderObject, $sendid, true ) ) {
				if( $shoppingOrderObject->settle_method == $this->getMethodNumber() ) {
					return $shoppingOrderObject;
				} else {
					return null;
				}
			}	
		}
		return null;
	}
	/**
	 * complete時の処理
	 */
	function settlement( & $request, & $shoppingOrderObject ) {
		$logMessage	= date('Y-m-d H:i:s')."\r\n";
		// アクセス制御
		if( $_SERVER['REMOTE_ADDR'] != '210.164.6.67'
			&& $_SERVER['REMOTE_ADDR'] != '202.221.139.50' ) {
			// アクセス元がゼウスカード決済サーバでない場合は処理しない
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','アクセス方法が正しくありません。');
			return false;
		}
		$dbo	= $request->getAttribute('dbo');
		// GETパラメータを取得
		$result		= trim(stripslashes($_GET['result']));
		$clientip	= trim(stripslashes($_GET['clientip']));
		$ordd		= trim(stripslashes($_GET['ordd']));
		$money		= trim(stripslashes($_GET['money']));
		$telno		= trim(stripslashes($_GET['telno']));
		$email		= trim(stripslashes($_GET['email']));
		$sendid		= trim(stripslashes($_GET['sendid']));
		$sendpoint	= trim(stripslashes($_GET['sendpoint']));
		$shoppingOrderObject->settle_log	.= "\r\n\r\n";
		if( 'OK' == $result ) {
			// 決済成功の場合
			$logMessage	.= "SETTLE=OK\r\n";
			$shoppingOrderObject->settleLogLn( $request, $logMessage );
			return true;
		} else {
			// 決済失敗の場合
			$logMessage	.= "SETTLE=NG\r\n";
			$shoppingOrderObject->settleLogLn( $request, $logMessage );
			return false;
		}
	}
	/**
	 * 妥当性検査時の処理
	 */
	function validate( & $request ) {
		$this->enable	= true;
		$isError	= false;
		if( 0 != $this->feeType ) {
			$request->addLocaledError('shopping.error.plugin.zeuscard.nocharge',SPIDER_LOG_LEVEL_ERROR,array());
			$isError	= false;
		} else {
			$this->feeType	= 0;
			$this->feeValue	= 0;
		}
		$this->settingValues['client_ip']	= mb_convert_kana($this->settingValues['client_ip'],'a');
		if( strlen(trim($this->settingValues['client_ip'])) == 0 ) {
			$this->enable	= false;
		} else if( preg_match('/^[0-9]+$/',$this->settingValues['client_ip']) == 0 ) {
			$request->addLocaledError('shopping.error.plugin.zeuscard.invalidipcode',SPIDER_LOG_LEVEL_ERROR,array());
		}
		if( $this->enable ) {
			if( strlen($this->settingValues['order_url']) == 0 ) {
			$request->addLocaledError('shopping.error.plugin.zeuscard.invalidurl',SPIDER_LOG_LEVEL_ERROR,array());
			}
			if( strlen($this->settingValues['credit_dev']) == 0 ) {
			} else {
				//'credit_dev'=>'VISA,MASTER,JCB,DINERS,AMEX',
				$this->settingValues['credit_dev']	= strtoupper($this->settingValues['credit_dev']);
				$valArray	= explode(',',$this->settingValues['credit_dev']);
				$newArray	= array();
				foreach( $valArray as $val ) {
					$val	= trim($val);
					if( preg_match('/^(VISA|MASTER|JCB|DINERS|AMEX)$/',$val) > 0 ) {
						array_push($newArray,$val);
					}
				}
				$this->settingValues['credit_dev']	= implode(',',$newArray);
			}
			if( $isError ) {
				$this->enable	= false;
			}
		}
		if( $request->isError() ) {
			return false;
		} else {
			return true;
		}
	}
	/**
	 * 決済状態同期のメソッド実装
	 * 注文オブジェクトを引数にとって外部サービスの決済状態と状態を同期します
	 * @param $request spider_HttpRequestインスタンス参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderインスタンス参照
	 * @return boolean 成功したらtrue/失敗したらfalse
	 */
	function settleSynchronize( & $request, & $shoppingOrderObject ) {
		// ゼウスサーバー側の現在の状態は確認できない
		return true;
	}
	/**
	 * 決済キャンセルメソッド実装
	 * @param $request spider_HttpRequestインスタンス参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderインスタンス参照
	 * @return boolean 成功したらtrue/失敗したらfalse
	 */
	function settleCancel( & $request, & $shoppingOrderObject ){
		// Secure Link Batchでキャンセル送信する
		$dbo		= $request->getAttribute('dbo');
		$logMessage	= date('Y-m-d H:i:s')."\r\n";
		if( strlen($shoppingOrderObject->settle_transaction_code) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','処理番号が正しく保存されていないためゼウスの決済をキャンセル処理できませんでした。');
			return false;
		}
		// キャンセル送信
		$httpRequest	= $this->zeusSettleCancel( $request, $shoppingOrderObject->settle_transaction_code );
		if( false === $httpRequest ) {
			$logMessage	.= "CANCEL=NG\r\n";
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		} else if( $request->isError() ) {
			// 通信エラーが発生している場合
			$logMessage	.= "CANCEL=NG\r\n";
			$logMessage	.= "Request Error No=".$httpRequest->errorNumber." ".$httpRequest->errorMessage;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','通信エラー番号:'.$httpRequest->errorNumber.' '.$httpRequest->errorMessage);
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 通信成功
		$responseCode	= $httpRequest->statusCode;
		$responseBody	= $httpRequest->responseBody;
		$shoppingOrderObject->settle_log	.= "\r\n\r\n";
		if( preg_match('/SuccessOK/',$responseBody) > 0 ) {
			// 処理成功
			$logMessage	.= "CANCEL=OK\r\n";
			$shoppingOrderObject->settleLogLn( $request, $logMessage );
			$shoppingOrderObject->setSettleDate( $request, $shoppingOrderObject->settle_date );
			return true;
		} else {
			// 処理失敗
			$logMessage	.= "CANCEL=NG\r\n";
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーでのキャンセル処理に失敗しました。お手数ですがゼウス管理画面で状態を確認してください。');
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
	}
	/**
	 * 決済金額変更メソッド実装
	 * @param $request spider_HttpRequestインスタンス参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderインスタンス参照
	 * @return boolean 成功したらtrue/失敗したらfalse
	 */
	function settleChangeAmount( & $request, & $shoppingOrderObject ){
		// Secure Link Batchで決済をやり直す
		$dbo		= $request->getAttribute('dbo');
		$logMessage	= date('Y-m-d H:i:s')."\r\n";
		if( strlen($shoppingOrderObject->settle_transaction_code) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','処理番号が正しく保存されていないためゼウスの決済金額変更処理できませんでした。お手数ですがゼウス管理画面から手動で金額変更してください。');
			return false;
		}
		// 新規決済作成: 新しい金額と前の情報で新規決済を作成する
		$httpRequest	= $this->zeusCreateNewSettlement( $request, $shoppingOrderObject );
		if( false === $httpRequest ) {
			$logMessage	.= "RENEW=NG\r\n";
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		} else if( $request->isError() ) {
			// 通信エラーが発生している場合
			$logMessage	.= "RENEW=NG\r\n";
			$logMessage	.= "Request Error No=".$httpRequest->errorNumber." ".$httpRequest->errorMessage;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','通信エラー番号:'.$httpRequest->errorNumber.' '.$httpRequest->errorMessage);
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 新規決済作成: 正常に通信できた場合 応答内容の解析
		$responseCode	= $httpRequest->statusCode;
		$responseBody	= trim($httpRequest->responseBody);
		$responseBody	= str_replace("\r\n","\n",$responseBody);
		$responseBody	= str_replace("\r","\n",$responseBody);
		if( preg_match('/Success\\_order/',$responseBody) == 0 ) {
			// 決済失敗
			$logMessage	.= "RENEW=NG\r\n";
			$logMessage	.= "\r\nResponse Status ".$responseCode."\r\n".$responseBody;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーでの新しい金額取引登録に失敗しました。お手数ですがゼウス管理画面で状態を確認してください。');
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 新規決済作成: 決済正常終了
		$oldTransactionCode	= $shoppingOrderObject->settle_transaction_code;
		$shoppingOrderObject->settle_transaction_code	= '';
		$paramArray	= explode("\n",$responseBody);
		foreach( $paramArray as $line ) {
			$line	= trim($line);
			if( strlen($line) > 0 && $line != 'Success_order' ) {
				// 新しく取得した処理IDに更新
				$shoppingOrderObject->setSettleTransactionCode( $request, $line );
				break;;
			}
		}
		// 新規決済作成: 決済ログ
		if( strlen($shoppingOrderObject->settle_transaction_code) == 0 ) {
			$logMessage	.= "RENEW=NG\r\n";
			$logMessage	.= "Old TransCode=".$oldTransactionCode."\r\n";
			$logMessage	.= "\r\nResponse Status ".$responseCode."\r\n".$responseBody;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーで新しい取引のID取得に失敗しました。お手数ですがゼウス管理画面で状態を確認してください。');
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		$logMessage	.= "RENEW=OK\r\n";
		$logMessage	.= "Old TransCode=".$oldTransactionCode."\r\n";
		$logMessage	.= "\r\nResponse Status ".$responseCode."\r\n".$responseBody."\r\n\r\n";
		
		// 前回決済削除: 処理ID取得に成功したら前回の決済を削除する
		$delResponseCode	= '';
		$delResponseBody	= '';
		$delHttpRequest	= $this->zeusSettleCancel( $request, $oldTransactionCode );
		if( false === $delHttpRequest ) {
			$logMessage	.= "DELETE OLD=NG\r\n";
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーで古い取引の削除に失敗しました。お手数ですがゼウス管理画面にログインして手動で削除してください。旧取引ID='.$oldTransactionCode);
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		} else if( $request->isError() ) {
			// 通信エラーが発生している場合
			$logMessage	.= "DELETE OLD=NG\r\n";
			$logMessage	.= "Request Error No=".$delHttpRequest->errorNumber." ".$delHttpRequest->errorMessage;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーで古い取引の削除に失敗しました。お手数ですがゼウス管理画面にログインして手動で削除してください。旧取引ID='.$oldTransactionCode.'  通信エラー番号:'.$delHttpRequest->errorNumber.' '.$delHttpRequest->errorMessage);
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 前回決済削除: 通信成功
		$delResponseCode	= $delHttpRequest->statusCode;
		$delResponseBody	= $delHttpRequest->responseBody;
		if( preg_match('/SuccessOK/',$delResponseBody) == 0 ) {
			// 決済失敗
			$logMessage	.= "DELETE OLD=NG\r\n";
			$logMessage	.= "\r\nResponse Status 旧取引ID=".$oldTransactionCode.' '.$responseCode."\r\n".$responseBody;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーで古い取引の削除に失敗しました。お手数ですがゼウス管理画面にログインして手動で削除してください。旧取引ID='.$oldTransactionCode.'  通信エラー番号:'.$delHttpRequest->errorNumber.' '.$delHttpRequest->errorMessage);
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 前回決済削除: 処理成功
		$logMessage	.= "DELETE OLD=OK\r\n";
		$logMessage	.= $responseBody;
		$shoppingOrderObject->settleLogLn( $request, $logMessage );
		$shoppingOrderObject->setSettlePrice($request,$shoppingOrderObject->payment_total);
		$shoppingOrderObject->setSettleDate( $request, $shoppingOrderObject->settle_date );
		return true;
	}
	/**
	 * 決済復帰メソッド
	 * @param $request spider_HttpRequestインスタンス参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderインスタンス参照
	 * @return boolean 成功したらtrue/失敗したらfalse
	 */
	function settleRecover( & $request, & $shoppingOrderObject ){
		// Secure Link Batchで決済をやり直す
		$dbo		= $request->getAttribute('dbo');
		$logMessage	= date('Y-m-d H:i:s')."\r\n";
		if( strlen($shoppingOrderObject->settle_transaction_code) == 0 ) {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','処理番号が正しく保存されていないためゼウスの決済金額変更処理できませんでした。お手数ですがゼウス管理画面をご確認ください。');
			return false;
		}
		// 新しい金額と前の情報で新規決済を作成する
		$httpRequest	= $this->zeusCreateNewSettlement( $request, $shoppingOrderObject );
		if( false === $httpRequest ) {
			$logMessage	.= "RECOVER=NG\r\n";
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		} else if( $request->isError() ) {
			// 通信エラーが発生している場合
			$logMessage	.= "RECOVER=NG\r\n";
			$logMessage	.= "Request Error No=".$httpRequest->errorNumber." ".$httpRequest->errorMessage;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','通信エラー番号:'.$httpRequest->errorNumber.' '.$httpRequest->errorMessage);
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 新規決済作成: 正常に通信できた場合 応答内容の解析
		$responseCode	= $httpRequest->statusCode;
		$responseBody	= trim($httpRequest->responseBody);
		$responseBody	= str_replace("\r\n","\n",$responseBody);
		$responseBody	= str_replace("\r","\n",$responseBody);
		if( preg_match('/Success\\_order/',$responseBody) == 0 ) {
			// 決済失敗
			$logMessage	.= "RECOVER=NG\r\n";
			$logMessage	.= "\r\nResponse Status ".$responseCode."\r\n".$responseBody;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーでの新しい金額取引登録に失敗しました。お手数ですがゼウス管理画面で状態を確認してください。');
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		// 新規決済作成: 決済正常終了
		$oldTransactionCode	= $shoppingOrderObject->settle_transaction_code;
		$shoppingOrderObject->settle_transaction_code	= '';
		$paramArray	= explode("\n",$responseBody);
		foreach( $paramArray as $line ) {
			$line	= trim($line);
			if( strlen($line) > 0 && $line != 'Success_order' ) {
				// 新しく取得した処理IDに更新
				$shoppingOrderObject->setSettleTransactionCode( $request, $line );
				break;;
			}
		}
		// 新規決済作成: 決済ログ
		if( strlen($shoppingOrderObject->settle_transaction_code) == 0 ) {
			$logMessage	.= "RECOVER=NG\r\n";
			$logMessage	.= "Old TransCode=".$oldTransactionCode."\r\n";
			$logMessage	.= "\r\nResponse Status ".$responseCode."\r\n".$responseBody;
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウス決済サーバーで新しい取引のID取得に失敗しました。お手数ですがゼウス管理画面で状態を確認してください。');
			$shoppingOrderObject->settleLogLn( $request, $logMessage."\r\n".implode("\n",$request->errors) );
			return false;
		}
		$logMessage	.= "RENEW=OK\r\n";
		$logMessage	.= "Old TransCode=".$oldTransactionCode."\r\n";
		$logMessage	.= "\r\nResponse Status ".$responseCode."\r\n".$responseBody."\r\n\r\n";
		$shoppingOrderObject->setSettlePrice($request,$shoppingOrderObject->payment_total);
		$shoppingOrderObject->setSettleDate( $request, $shoppingOrderObject->settle_date );
		$shoppingOrderObject->settleLogLn( $request, $logMessage );
		return true;
	}
	/**
	 * ゼウス固有メソッド：処理IDを指定して取引をキャンセルします
	 * @param $request spider_HttpRequestインスタンス参照
	 * @param $settleTransactionCode shopping_DaoShoppingOrder->settle_transaction_code
	 * @return util_HttpRequestクラスオブジェクト 通信を行わなかった場合はfalse
	 */
	function zeusSettleCancel( & $request, $settleTransactionCode ) {
		if( strlen($settleTransactionCode) > 0 ) {
			// httpリクエストオブジェクト作成
			$httpRequest	= new util_HttpRequest($this->settingValues['order_url'],'post');
			// 基本情報設定
			$httpRequest->addPostData('clientip', $this->settingValues['client_ip']);
			$httpRequest->addPostData('return', 'yes');
			$httpRequest->addPostData('ordd', $settleTransactionCode);
			// HTTPリクエスト実行
			if( $httpRequest->send(null,60) ) {
				return $httpRequest;
			} else {
				// リクエストエラー
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウスの決済サーバーに正常なリクエストを送信できないか不明な応答が帰ってきました。お手数ですがゼウス管理画面で正常に処理できているか確認してください。');
				return $httpRequest;
			}
		} else {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','処理番号が正しく保存されていないため決済キャンセル処理できません。お手数ですがゼウス管理画面から手動で決済キャンセル変更してください。');
			return false;
		}
	}
	/**
	 * ゼウス固有メソッド：現在の決済IDを元に新しい決済を作成します
	 * 新しい決済は$shoppingOrderObject->payment_totalにセットされている数値で金額を決定します
	 * @param $request spider_HttpRequestインスタンス参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderインスタンス参照
	 * @return util_HttpRequestクラスオブジェクト 通信を行わなかった場合はfalse
	 */
	function zeusCreateNewSettlement( & $request, & $shoppingOrderObject ) {
		if( $shoppingOrderObject->settle_transaction_code ) {
			$dbo	= $request->getAttribute('dbo');
			// 決済ログから分割回数を取り出す
			$zeuscarddiv	= '01';
			if( preg_match('/zeusecarddiv=([0-9]{2})/',$shoppingOrderObject->settle_log,$matches) > 0 ) {
				$zeuscarddiv	= trim($matches[1]);
			}
			// 新しい金額と前の情報で新規決済を作成する
			// httpリクエストオブジェクト作成
			$httpRequest	= new util_HttpRequest($this->settingValues['order_url'],'post');
			$httpRequest->addPostData('clientip', $this->settingValues['client_ip']);
			// カード番号はshopformer注文IDでカード番号を検索する固定値9999999999999992
			$httpRequest->addPostData('cardnumber', '9999999999999992');
			// 分割回数は最初の決済から変更できない
			$httpRequest->addPostData('div', $zeuscarddiv);
			// 年月はダミー
			$httpRequest->addPostData('expyy', date('y') );
			$httpRequest->addPostData('expmm', date('m') );
			// 決済通貨の指定（暫定：固定円）
			$httpRequest->addPostData('send', 'mall');
			// usernameは空で固定
			$httpRequest->addPostData('username', '');
			$memberObject	= $shoppingOrderObject->memberObject;
			if( is_null($memberObject) || strlen($memberObject->member_number) == 0 ) {
				$dbo->loadById( $memberObject, $shoppingOrderObject->member_id );
			}
			$email			= null;
			if( strlen($memberObject->pc_mail) > 0 ) {
				$email	= $memberObject->pc_mail;
			} else if( strlen($memberObject->mb_mail) > 0 ) {
				$email	= $memberObject->mb_mail;
			}
			$httpRequest->addPostData('sendid', $shoppingOrderObject->order_id);
			$httpRequest->addPostData('telno', str_replace('-','',$shoppingOrderObject->memberObject->telephone_number));
			$httpRequest->addPostData('email', $email);
			// 決済金額
			$httpRequest->addPostData('money', $shoppingOrderObject->payment_total);
			// レスポンス時にゼウス側のオーダー番号を取得する
			$httpRequest->addPostData('printord', 'yes');
			// HTTPリクエスト実行
			if( $httpRequest->send(null,60) ) {
				return $httpRequest;
			} else {
				$shoppingOrderObject->addColumnError($request,'settle_method_errors','ゼウスの決済サーバーに正常なリクエストを送信できないか不明な応答が帰ってきました。お手数ですがゼウス管理画面で正常に処理できているか確認してください。');
				return $httpRequest;
			}
		} else {
			$shoppingOrderObject->addColumnError($request,'settle_method_errors','処理番号が正しく保存されていないため決済金額変更処理できません。お手数ですがゼウス管理画面から手動で金額変更してください。');
			return false;
		}
	}
}
?>