/*********************************************************************
 * All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JKKCtrlPaygentAzkAuthInfoImpl
 *   ソースファイル名：JKKCtrlPaygentAzkAuthInfoImpl.java
 *   作成者          ：富士通
 *   日付            ：2022年04月14日
 *＜機能概要＞
 *   ペイジェントシステム預かりオーソリ連携処理部品です。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v58.00.00	2022/04/14	 FJ) 上村	 【ANK-3846-00-00】【クレカ】ペイジェント→ペイジェント移行
 *   v58.00.00	2022/06/27	 FJ) 北村	 【ANK-3846-09-00】【クレカ】ペイジェント→ペイジェント移行
 **********************************************************************/
package eo.ejb.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.sql.Connection;
import java.util.HashMap;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.ws.http.HTTPException;

import com.fujitsu.futurity.common.JSYLogBase;
import com.fujitsu.futurity.common.JSYbpmLog;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import eo.common.util.JCCFrameworkException;
import eo.common.util.JCNAuthResultCdConvertUtil;
import eo.ejb.cbm.entity.ZM0321ETMsg;
import eo.ejb.cbs.cbsmsg.EKKA0010003CBSMsg;

public class JKKCtrlPaygentAzkAuthInfoImpl{
	
	/**
	 * ペイジェントシステム接続モード（本番）
	 */
	private static final String PAYGENT_SYSTEM = "PAYGENT_SYSTEM";
	
	/**
	 * ペイジェントシステム接続モード（スタブ）
	 */
	private static final String PAYGENT_STUB = "PAYGENT_STUB";
	
	/**
	 * マーチャントID
	 */
	private static final String MERCHANT_ID = "merchant_id";

	/**
	 * 接続ID
	 */
	private static final String CONNECT_ID = "connect_id";
	
	/**
	 * 接続パスワード
	 */
	private static final String CONNECT_PASSWORD = "connect_password";
	
	/**
	 * 電文種別
	 */
	private static final String TELEGRAM_KIND = "telegram_kind";
	
	/**
	 * 電文バージョン番号
	 */
	private static final String TELEGRAM_VERSION = "telegram_version";
	
	/**
	 * マーチャント取引ＩＤ
	 */
	private static final String TRADING_ID = "trading_id";
	
	/**
	 * 決済ID
	 */
	private static final String PAYMENT_ID = "payment_id";
	
	/**
	 * 顧客ID
	 */
	private static final String CUSTOMER_ID = "customer_id";
	
	/**
	 * カード番号
	 */
	private static final String CARD_NUMBER = "card_number";
	
	/**
	 * カード有効期限
	 */
	private static final String CARD_VALID_TERM = "card_valid_term";
	
	/**
	 * カード確認番号
	 */
	private static final String CARD_CONF_NUMBERM = "card_conf_number";
	
	/**
	 * カードブランド
	 */
	private static final String CARD_BRAND = "card_brand";
	
	/**
	 * カード名義人
	 */
	private static final String CARDHOLDER_NAME = "cardholder_name";
	
	/**
	 * 補足情報1
	 */
	private static final String ADD_INFO1 = "add_info1";
	
	/**
	 * 補足情報2
	 */
	private static final String ADD_INFO2 = "add_info2";
	
	/**
	 * 補足情報3
	 */
	private static final String ADD_INFO3 = "add_info3";
	
	/**
	 * 補足情報4
	 */
	private static final String ADD_INFO4 = "add_info4";

	/**
	 * サイトID
	 */
	private static final String SITE_ID = "site_id";
	
	/**
	 * 有効性チェックフラグ
	 */
	private static final String VALID_CHECK_FLG = "valid_check_flg";
	
	/**
	 * カード情報トークン
	 */
	private static final String CARD_TOKEN = "card_token";
	
	/**
	 * セキュリティコード利用
	 */
	private static final String SECURITY_CODE_USE = "security_code_use";
	
	/**
	 * 電文種別ID（預かりオーソリ）
	 */
	private static final String TELEGRAM_KIND_ID_VALUE = "025";
	
	/**
	 * 有効性チェックフラグ（1：確認する）
	 */
	private static final String VALID_CHECK_FLG_VALUE = "1";
	
	/**
	 * 処理結果
	 */
	private static final String RESULT = "result";
	
	/**
	 * レスポンスコード
	 */
	private static final String RESPONSE_CODE = "response_code";
	
	/**
	 * レスポンス詳細
	 */
	private static final String RESPONSE_DETAIL = "response_detail";
	
	/**
	 * フィンガープリント
	 */
	private static final String FINGERPRINT = "fingerprint";
	
	/**
	 * マスクされたカード番号
	 */
	private static final String MASKED_CARD_NUMBER = "masked_card_number";
	
	/**
	 * 取扱カード会社コード
	 */
	private static final String ACQ_ID = "acq_id";
	
	/**
	 * デビット・プリペイド判定結果
	 */
	private static final String DEBIT_PREPAID_TYPE = "debit_prepaid_type";
	
	/**
	 * イシュア区分
	 */
	private static final String ISSUR_CLASS = "issur_class";

	/** ペイジェントAPIシステムエラー */
	private static final String S_AUTH_SYSERR = "9000000";
	
	/** 通信方式SSL */
	private static final String S_HTTPS = "https";
	
	/** 通信方式パラメータ */
	private static final String S_SSL = "SSL";
	
	/** リクエスト種別パラメータ */
	private static final String S_POST = "POST";
	
	/** パラメータセパレート文字:= */
	private static final String S_SEP_EQ = "=";
	
	/** パラメータ区切り文字:& */
	private static final String NEW_LINE_AND = "&";
	
	/** 文字コード */
	private static final String S_CHR_CODE = "Shift-JIS";
	
	/** レスポンス区切り文字 */
	private static final String S_DELIM_TAB = "=";
	
	/**
	 * ペイジェントシステム預かりオーソリ連携処理部品です。
	 * @param inCBSMsg CAANメッセージ
	 * @param inContext コンテキスト
	 * @throws Exception 
	 */
	public void ctrlPaygentAzkAuth(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws Exception
	{
		// 開始ログ出力を実施。
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#ctrlPaygentAzkAuth start");
		
		// スタブ利用フラグ設定
		String stb_use_flg = "";
		// ペイジェント返却値設定用MAP作成
		HashMap<String,String> resultMap = new HashMap<String,String>();
		
		// ペイジェントシステム接続モードを取得
		String sys_mode = JCCModelCommon.getApplicationConst("PAYGENT_CONNECTION_MODE");
		
		// スタブ利用フラグを決定
		if(sys_mode.equals(PAYGENT_SYSTEM))
		{
			// "利用なし"を設定
			stb_use_flg = "0";
		}
		else if(sys_mode.equals(PAYGENT_STUB))
		{
			// "利用あり"を設定
			stb_use_flg = "1";
		}
		
		// オーソリ依頼連携を実施
		// トークン情報を取得
		String card_token = inCBSMsg.getString(EKKA0010003CBSMsg.PY_CARD_TOKEN);
		
		// 取得したトークンの1文字目を保持
		String stb_key = card_token.substring(0, 1);
		
		// スタブ利用フラグが"1：利用あり"かつトークンの1文字目が"9"以外の場合、スタブテーブルを利用
		if ("1".equals(stb_use_flg) && !"9".equals(stb_key)) {
			try
			{
				StringBuilder logStr = new StringBuilder();
				
				logStr.append(TELEGRAM_KIND + "=");
				logStr.append(TELEGRAM_KIND_ID_VALUE + ",");
				logStr.append(TRADING_ID + "=");
				logStr.append("" + ",");
				logStr.append(PAYMENT_ID + "=");
				logStr.append("" + ",");
				logStr.append(CUSTOMER_ID + "=");
				logStr.append("" + ",");
				logStr.append(CARD_NUMBER + "=");
				logStr.append("" + ",");
				logStr.append(CARD_VALID_TERM + "=");
				logStr.append("" + ",");
				logStr.append(CARD_CONF_NUMBERM + "=");
				logStr.append("" + ",");
				logStr.append(CARD_BRAND + "=");
				logStr.append("" + ",");
				logStr.append(CARDHOLDER_NAME + "=");
				logStr.append("" + ",");
				logStr.append(ADD_INFO1 + "=");
				logStr.append("" + ",");
				logStr.append(ADD_INFO2 + "=");
				logStr.append("" + ",");
				logStr.append(ADD_INFO3 + "=");
				logStr.append("" + ",");
				logStr.append(ADD_INFO4 + "=");
				logStr.append("" + ",");
				logStr.append(SITE_ID + "=");
				logStr.append(inCBSMsg.getString(EKKA0010003CBSMsg.PY_SITE_ID) + ",");
				logStr.append(VALID_CHECK_FLG + "=");
				logStr.append(VALID_CHECK_FLG_VALUE + ",");
				logStr.append(CARD_TOKEN + "=");
				logStr.append(inCBSMsg.getString(EKKA0010003CBSMsg.PY_CARD_TOKEN) + ",");
				logStr.append(SECURITY_CODE_USE + "=");
				logStr.append(inCBSMsg.getString(EKKA0010003CBSMsg.PY_SECURITY_CODE_USE));
				
				JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,
						"ペイジェント入力結果=" + logStr.toString(), "",  new String[]{"", ""}, "");
				
				// テーブル取得スタブ用、
				JKKPaygentStbInfo instance = JKKPaygentStbInfo.getInstance();
				
				// テーブルのコネクションを取得して、部品に受け渡しを行う。
				Connection con = JSYejbConnection.getConnection("PY_T_PAYGENT_STB");
				instance.setConnection(con);
				// ペイジェントシステムオーソリ連携処理部品（スタブ）処理を実行
				resultMap = instance.ctrlPaygentAuthStb(inCBSMsg, inContext, TELEGRAM_KIND_ID_VALUE);

				// カード受付情報登録処理の呼出し
				JKKCardUkInfoInsCtrlUtil.insCardUkInfo(inCBSMsg, resultMap, "025");
				
			}
			catch(Exception ex)
			{
				throw new CAANRuntimeException(ex);
			}
		} else {
			
			HttpURLConnection conn = null;
			URL url = null;
			
			try
			{
				//system.properties設定値取得
				String strUrl = JCMAPLConstMgr.getString("KK_PAYGENT_URL");
				String strApiNm = JCMAPLConstMgr.getString("KK_PAYGENT_APINAME");
				int timeout = Integer.parseInt(JCMAPLConstMgr.getString("KK_PAYGENT_TIMEOUT"));
				int retryCount = Integer.parseInt(JCMAPLConstMgr.getString("KK_PAYGENT_RETRYCOUNT"));
				int retryInterval = Integer.parseInt(JCMAPLConstMgr.getString("KK_PAYGENT_RETRYINTERVAL"));	
				
				
				// 業務パラメータ管理.マーチャントＩＤ
				// クラスのインスタンス化
				JCHModelCommon jchCommon = new JCHModelCommon();
				CAANMsg paramList = jchCommon.getGyoumuParam(inCBSMsg.getString(EKKA0010003CBSMsg.PY_MERCHANT_ID));
				String merchant_id = paramList.getString(ZM0321ETMsg.WORK_PARAM_SETTE_VALUE);
				// アプリケーションプロパティ.接続ID
				String connect_id = JCMAPLConstMgr.getString(inCBSMsg.getString(EKKA0010003CBSMsg.PY_CONNECT_ID));
				// アプリケーションプロパティ.接続パスワード
				String connect_password = JCMAPLConstMgr.getString(inCBSMsg.getString(EKKA0010003CBSMsg.PY_CONNECT_PASSWORD));
				// アプリケーションプロパティ.電文バージョン番号
				String telegram_version = JCMAPLConstMgr.getString(inCBSMsg.getString(EKKA0010003CBSMsg.PY_TELEGRAM_VERSION));
				
				// アプリケーションプロパティ設定チェック
				if(strUrl == null
						|| strApiNm == null
						|| merchant_id == null
						|| connect_id == null
						|| connect_password == null
						|| telegram_version == null)
				{
					inCBSMsg.set(EKKA0010003CBSMsg.PY_RESULTCODE, S_AUTH_SYSERR);
					return;
				}
				
				// 通信方式判定
				boolean bSslFlg = false;
				if(strUrl.startsWith(S_HTTPS))
				{
					bSslFlg = true;
				}
				
				// SSL通信の場合、キーマネージャを生成
				if(bSslFlg)
				{
					KeyManager[] km = null;
					TrustManager[] tm = { new X509TrustManager() {
		
						/**
						 * X509Certificateスタブメソッド
						 * @return null
						 */
						public java.security.cert.X509Certificate[] getAcceptedIssuers() 
						{
							return null;
						}
		
						/**
						 * checkClientTrustedスタブメソッド
						 * @param arg0
						 * @param arg1
						 * @throws CertificateException
						 */
						public void checkClientTrusted(
								java.security.cert.X509Certificate[] arg0, String arg1)
								throws CertificateException 
						{
						}
		
						/**
						 * checkServerTrustedスタブメソッド
						 * @param arg0
						 * @param arg1
						 * @throws CertificateException
						 */
						public void checkServerTrusted(
								java.security.cert.X509Certificate[] arg0, String arg1)
								throws CertificateException 
						{
						}
					} };
					SSLContext sslcontext = SSLContext.getInstance(S_SSL);
					sslcontext.init(km, tm, new SecureRandom());
					HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
						
						/**
						 * verifyスタブメソッド
						 * @param aHostname
						 * @param aSession
						 * @return ペイジェントAPIへのリクエストパラメータ
						 */
						public boolean verify(String aHostname, SSLSession aSession) 
						{
							return true;
						}
					});
					HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
				}
				
				// URL生成
				url = new URL(strUrl + strApiNm);
				// リクエスト結果読込用ストリーム
				InputStream is = null;
				
				for(int i = 0 ; i < retryCount ; i++)
				{
					try
					{
						// アプリケーションプロパティよりProxy設定値を取得
						String strPrxyHost = JCMAPLConstMgr.getString("CN_HTTPS_PROXY_HOST");
						String strPrxyPort = JCMAPLConstMgr.getString("CN_HTTPS_PROXY_PORT");
						
						int intProxyPort = 0;
						if(strPrxyHost != null)
						{
							intProxyPort = Integer.parseInt(strPrxyPort);
						}
						
						// SSLの場合、HttpsURLConnectionへキャスト
						if(bSslFlg)
						{
							// Proxy設定値がある場合はProxyをセットしてコネクションをオープン
							if(strPrxyHost != null
									&& strPrxyPort != null)
							{
								Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(strPrxyHost, intProxyPort));
								conn = (HttpsURLConnection) url.openConnection(proxy);
							}
							else
							{
								conn = (HttpsURLConnection) url.openConnection();
							}
							
						}
						else
						{
							conn = (HttpURLConnection) url.openConnection();
						}
						
						
						// リクエスト設定
						conn.setRequestMethod(S_POST);
						conn.setDoOutput(true);
						conn.setInstanceFollowRedirects(true);
						conn.setRequestProperty("Accept-Language", "jp");
						// 未設定の場合は「Content-Type:application/x-www-form-urlencoded」となる
						conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + S_CHR_CODE);
						
						//タイムアウト設定
						conn.setReadTimeout(timeout);
						
						//POSTパラメータストリームの生成
						OutputStream os = conn.getOutputStream();
						PrintStream ps = new PrintStream(os);
						ps.print(requestParamMake(inCBSMsg, merchant_id, connect_id, telegram_version, connect_password));
						ps.close();
						
						// 接続開始ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#connect start");
						
						// 接続実行
						conn.connect();
						
						// 接続終了ログ
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#connect end");
						
						int statusCode = 500;
						statusCode = conn.getResponseCode();

						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#statusCode=" + statusCode);
						
						//リクエスト結果読み出し
						is = conn.getInputStream();
						BufferedReader reader = new BufferedReader(new InputStreamReader(is, S_CHR_CODE));
						
						String s = null;
						
						for(s = reader.readLine() ; null != s ; s = reader.readLine()) {
							
							// 読込んだ文字列が空白またはnullの場合、
							if (isNullBlank(s)) {
								// レスポンスの読込処理をスキップする
								continue;
							}
							
							String delim = S_DELIM_TAB;
							// レスポンス読込結果をキーと値に分割
							String[] res = s.split(delim);
							String key = res[0];
							String value = "";
							if (res.length == 2) {
								value = URLDecoder.decode(res[1],S_CHR_CODE);
							}
							//ペイジェントAPI処理結果をマップに格納する
							resultMap.put(key, value);
						}
						
						// カード受付情報登録処理の呼出し
						JKKCardUkInfoInsCtrlUtil.insCardUkInfo(inCBSMsg, resultMap, "025");
						
						/**
						 * 下り電文のログ出力
						 */
						JSYejbLog.outlog(null, JSYejbLog.EXECUTION, this.getClass(), "SOAPレスポンス読込処理 START");
						JSYejbLog.outlog(null, JSYejbLog.EXECUTION, this.getClass(), resultMap);
						JSYejbLog.outlog(null, JSYejbLog.EXECUTION, this.getClass(), "SOAPレスポンス読込処理 END");

						// 通信レスポンスコードが異常だった場合は処理結果にシステムエラーを設定
						if (statusCode != 200) 
						{
							inCBSMsg.set(EKKA0010003CBSMsg.PY_RESULTCODE, S_AUTH_SYSERR);
						}
					}
					catch(HTTPException he)
					{
						inCBSMsg.set(EKKA0010003CBSMsg.PY_RESULTCODE, S_AUTH_SYSERR);
						
						StringBuilder sb = new StringBuilder();
						StringWriter sw = new StringWriter();
						PrintWriter pw = new PrintWriter(sw);
						he.printStackTrace(pw);
						sb.append("\n" + sw.toString());
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(),"#JKKCtrlPaygentAzkAuthInfoImpl(HTTPException)発生" + sb.toString());
						
						// リトライ
						if(i < retryCount)
						{
							// スリープ開始ログ
							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#sleep start");
							// スリープ処理
							Thread.sleep(retryInterval);
							// スリープ終了ログ
							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#sleep end");
							// リトライカウントログ
							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#retryCount="
									+ i);
							continue;
						}
						else
						{
							throw he;
						}
					}
					catch(IOException ie)
					{
						inCBSMsg.set(EKKA0010003CBSMsg.PY_RESULTCODE, S_AUTH_SYSERR);
						
						StringBuilder sb = new StringBuilder();
						StringWriter sw = new StringWriter();
						PrintWriter pw = new PrintWriter(sw);
						ie.printStackTrace(pw);
						sb.append("\n" + sw.toString());
						JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(),"#JKKCtrlPaygentAzkAuthInfoImpl(IOException)発生" + sb.toString());
						
						// リトライ
						if(i < retryCount)
						{
							// スリープ開始ログ
							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#sleep start");
							// スリープ処理
							Thread.sleep(retryInterval);
							// スリープ終了ログ
							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#sleep end");
							// リトライカウントログ
							JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#retryCount="
									+ i);
							continue;
						}
						else
						{
							throw ie;
						}
					}				
					finally
					{
						if(is != null)
						{
							is.close();
							is = null;
						}
					}
					break;
				}
				
			}
			catch (Exception e)
			{
				StringBuilder sb = new StringBuilder();
				StringWriter sw = new StringWriter();
				PrintWriter pw = new PrintWriter(sw);
				e.printStackTrace(pw);
				sb.append("\n" + sw.toString());
				JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(),"#JKKCtrlPaygentAzkAuthInfoImpl(Exception)発生" + sb.toString());
				
				inCBSMsg.set(EKKA0010003CBSMsg.PY_RESULTCODE, S_AUTH_SYSERR);
				return;
			}
			finally
			{
				if (conn != null)
				{
					//切断処理
					conn.disconnect();
					conn = null;
				}
			}
		}
		
		StringBuffer sb = new StringBuffer();
		sb.append("ペイジェント出力結果=");
		sb.append(makeLogStr(resultMap));
		JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,sb, "",  new String[]{"", ""}, "");
		
		// 出力情報の格納
		resultPut(inCBSMsg, resultMap);
		
		// 処理結果ログ出力
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_RESULTCODE=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_RESULTCODE));	// 処理結果コード
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_RESPONSE_CODE=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_RESPONSE_CODE));		// レスポンスコード
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_RESPONSE_DETAIL=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_RESPONSE_DETAIL));	// レスポンス詳細
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_NUM_OF_CARDS=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_NUM_OF_CARDS));	// 顧客カード数
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_CUSTOMER_CARD_ID=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_CUSTOMER_CARD_ID));	// 顧客カードID
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_ISSUR_ID=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_ISSUR_ID));	// カード発行会社コード
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_ISSUR_NAME=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_ISSUR_NAME));	// カード発行会社名
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_FINGERPRINT=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_FINGERPRINT));	// フィンガープリント
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_MASKED_CARD_NUMBER=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_MASKED_CARD_NUMBER));	// マスクされたカード番号
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_CARD_VALID_TERM=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_CARD_VALID_TERM));	// カード有効期限
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_CARDHOLDER_NAME=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_CARDHOLDER_NAME));	// カード名義人
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_ACQ_ID=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_ACQ_ID));	// 取扱カード会社コード
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_ACQ_NAME=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_ACQ_NAME));	// 取扱カード会社名
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_CUSTOMER_ID=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_CUSTOMER_ID));	// 顧客ID
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_DEBIT_PREPAID_TYPE=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_DEBIT_PREPAID_TYPE));	// デビット・プリペイド判定結果
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_ISSUR_CLASS=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_ISSUR_CLASS));	// イシュア区分
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#PY_ACQ_NAME=" + 
				inCBSMsg.getString(EKKA0010003CBSMsg.PY_ACQ_NAME));	// カードブランド
		
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#ctrlPaygentAzkAuth end");
	}
	
	/**
	 * ペイジェントAPIに対して送信するリクエストパラメータを作成する。
	 * @param inCBSMsg メッセージキャリア
	 * @param merchant_id マーチャントＩＤ
	 * @param connect_id 接続ID
	 * @param telegram_version 電文バージョン番号
	 * @param strCrPasswd 接続パスワード（複合化後）
	 * @return ペイジェントAPIへのリクエストパラメータ
	 */
	private String requestParamMake(CAANMsg inCBSMsg, String merchant_id, String connect_id, String telegram_version, String strCrPasswd)
	{

		// リクエストパラメータ作成(CBSMsgより読み出し)
		StringBuffer strBuf = new StringBuffer();

		// リクエスト.サイトID
		String site_id = inCBSMsg.getString(EKKA0010003CBSMsg.PY_SITE_ID);
		
		// リクエスト.カード情報トークン
		String card_token = inCBSMsg.getString(EKKA0010003CBSMsg.PY_CARD_TOKEN);
		
		// リクエスト.セキュリティコード利用
		String security_code_use = inCBSMsg.getString(EKKA0010003CBSMsg.PY_SECURITY_CODE_USE);
		
		try
		{
			// マーチャントID
			strBuf.append(MERCHANT_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(merchant_id,S_CHR_CODE));
			strBuf.append(NEW_LINE_AND);
			
			// 接続ID
			strBuf.append(CONNECT_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(connect_id,S_CHR_CODE));
			strBuf.append(NEW_LINE_AND);
			
			// 接続パスワード
			strBuf.append(CONNECT_PASSWORD);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(strCrPasswd,S_CHR_CODE));
			strBuf.append(NEW_LINE_AND);
			
			// 電文種別
			strBuf.append(TELEGRAM_KIND);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(TELEGRAM_KIND_ID_VALUE,S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 電文バージョン番号
			strBuf.append(TELEGRAM_VERSION);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(telegram_version,S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// マーチャント取引ＩＤ
			strBuf.append(TRADING_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 決済ID
			strBuf.append(PAYMENT_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 顧客ID
			strBuf.append(CUSTOMER_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// カード番号
			strBuf.append(CARD_NUMBER);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// カード有効期限
			strBuf.append(CARD_VALID_TERM);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// カード確認番号
			strBuf.append(CARD_CONF_NUMBERM);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// カードブランド
			strBuf.append(CARD_BRAND);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// カード名義人
			strBuf.append(CARDHOLDER_NAME);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 補足情報1
			strBuf.append(ADD_INFO1);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 補足情報2
			strBuf.append(ADD_INFO2);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 補足情報3
			strBuf.append(ADD_INFO3);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 補足情報4
			strBuf.append(ADD_INFO4);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode("",S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// サイトID
			strBuf.append(SITE_ID);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(site_id,S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// 有効性チェックフラグ
			strBuf.append(VALID_CHECK_FLG);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(VALID_CHECK_FLG_VALUE,S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// カード情報トークン
			strBuf.append(CARD_TOKEN);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(card_token,S_CHR_CODE));
			
			strBuf.append(NEW_LINE_AND);
			
			// セキュリティコード利用
			strBuf.append(SECURITY_CODE_USE);
			strBuf.append(S_SEP_EQ);
			strBuf.append(URLEncoder.encode(security_code_use,S_CHR_CODE));
		}
		catch (UnsupportedEncodingException ue)
		{
			throw new JCCFrameworkException("不正なエンコードが指定されました。", ue);
		}
		
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), "JKKCtrlPaygentAzkAuthInfoImpl#requestParamMake=" + strBuf.toString());

		StringBuilder logStr = new StringBuilder();
		
		logStr.append(MERCHANT_ID + "=");
		logStr.append(merchant_id + ",");
		logStr.append(CONNECT_ID + "=");
		logStr.append(connect_id + ",");
		logStr.append(CONNECT_PASSWORD + "=");
		logStr.append(strCrPasswd + ",");
		logStr.append(TELEGRAM_KIND + "=");
		logStr.append(TELEGRAM_KIND_ID_VALUE + ",");
		logStr.append(TELEGRAM_VERSION + "=");
		logStr.append(telegram_version + ",");
		logStr.append(TRADING_ID + "=");
		logStr.append("" + ",");
		logStr.append(PAYMENT_ID + "=");
		logStr.append("" + ",");
		logStr.append(CUSTOMER_ID + "=");
		logStr.append("" + ",");
		logStr.append(CARD_NUMBER + "=");
		logStr.append("" + ",");
		logStr.append(CARD_VALID_TERM + "=");
		logStr.append("" + ",");
		logStr.append(CARD_CONF_NUMBERM + "=");
		logStr.append("" + ",");
		logStr.append(CARD_BRAND + "=");
		logStr.append("" + ",");
		logStr.append(CARDHOLDER_NAME + "=");
		logStr.append("" + ",");
		logStr.append(ADD_INFO1 + "=");
		logStr.append("" + ",");
		logStr.append(ADD_INFO2 + "=");
		logStr.append("" + ",");
		logStr.append(ADD_INFO3 + "=");
		logStr.append("" + ",");
		logStr.append(ADD_INFO4 + "=");
		logStr.append("" + ",");
		logStr.append(SITE_ID + "=");
		logStr.append(site_id + ",");
		logStr.append(VALID_CHECK_FLG + "=");
		logStr.append(VALID_CHECK_FLG_VALUE + ",");
		logStr.append(CARD_TOKEN + "=");
		logStr.append(card_token + ",");
		logStr.append(SECURITY_CODE_USE + "=");
		logStr.append(security_code_use);
		
		JSYbpmLog.println(JSYLogBase.EXECUTION, this.getClass() ,
				"ペイジェント入力結果=" + logStr.toString(), "",  new String[]{"", ""}, "");
		
		return strBuf.toString();
	}
	
	/**
	 * ペイジェントAPI処理結果を格納する。
	 * @param inCBSMsg メッセージキャリア
	 * @param resultMap レスポンス情報
	 */
	private void resultPut(CAANMsg inCBSMsg, HashMap<String,String> resultMap)
	{

		// レスポンスコードを取得
		String response_code = (String)resultMap.get(RESPONSE_CODE);
		// レスポンス詳細を取得
		String response_detail = (String)resultMap.get(RESPONSE_DETAIL);
		
		if (isNullBlank(response_code)) {
			// レスポンスコードがnullまたは""の場合、
			response_code = "";
		}
		
		if (!isNullBlank(response_detail)) {
			// レスポンス詳細がnullまたは""でない場合、
			// レスポンス詳細より"(ダブルクォーテーション)を削除する
			response_detail = response_detail.replaceAll("\"", "");
		} else {
			response_detail = "";
		}
		
		// オーソリ結果変換部品インスタンスを作成
		JCNAuthResultCdConvertUtil convertUtil = new JCNAuthResultCdConvertUtil((String)resultMap.get(RESULT), 
							response_code, 
							response_detail, 
							(String)resultMap.get(MASKED_CARD_NUMBER), 
							(String)resultMap.get(DEBIT_PREPAID_TYPE),
							(String)resultMap.get(CARD_BRAND),
							(String)resultMap.get(CARD_VALID_TERM));
		
		// ペイジェントより取得したコードを利用して、処理結果コードに変換し返却する
		inCBSMsg.set(EKKA0010003CBSMsg.PY_RESULTCODE, convertUtil.convertResultCd());
				
		// 変換部品ログ
		JSYejbLog.println(JSYejbLog.EXECUTION, this.getClass(),"処理結果コード変換ログ:"+ 
						"処理結果="+(String)resultMap.get(RESULT)+
						":レスポンスコード="+response_code+
						":レスポンス詳細="+response_detail+
						":処理結果コード="+inCBSMsg.getString(EKKA0010003CBSMsg.PY_RESULTCODE));

		// レスポンスコードを設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_RESPONSE_CODE, response_code);
		
		// レスポンス詳細を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_RESPONSE_DETAIL, response_detail);
		
		// 顧客カード数
		// ""(空)を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_NUM_OF_CARDS, "");
		
		// 顧客カードID
		// ""(空)を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_CUSTOMER_CARD_ID, "");
		
		// カード発行会社コード
		// ""(空)を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_ISSUR_ID, "");
		
		// カード発行会社名
		// ""(空)を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_ISSUR_NAME, "");
		
		// フィンガープリント
		if(!isNullBlank((String)resultMap.get(FINGERPRINT))){
			// フィンガープリントを設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_FINGERPRINT, resultMap.get(FINGERPRINT));
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_FINGERPRINT, "");
		}
		
		// マスクされたカード番号
		if(!isNullBlank((String)resultMap.get(MASKED_CARD_NUMBER))){
			// マスクされたカード番号を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_MASKED_CARD_NUMBER, convertUtil.convertCreCardNo());
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_MASKED_CARD_NUMBER, "");
		}
		
		// カード有効期限
		if(!isNullBlank((String)resultMap.get(CARD_VALID_TERM))){
			// カード有効期限を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_CARD_VALID_TERM, convertUtil.convertCardValidTerm());
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_CARD_VALID_TERM, "");
		}
		
		// カード名義人
		// ""(空)を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_CARDHOLDER_NAME, "");
		
		// 取扱カード会社コード
		if(!isNullBlank((String)resultMap.get(ACQ_ID))){
			// 取扱カード会社コードを設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_ACQ_ID, resultMap.get(ACQ_ID));
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_ACQ_ID, "");
		}
		
		// 取扱カード会社名
		// ""(空)を設定
		inCBSMsg.set(EKKA0010003CBSMsg.PY_ACQ_NAME, "");
		
		// 顧客ID
		if(!isNullBlank((String)resultMap.get(CUSTOMER_ID))){
			// 顧客IDを設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_CUSTOMER_ID, resultMap.get(CUSTOMER_ID));
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_CUSTOMER_ID, "");
		}
		
		// デビット・プリペイド判定結果
		if(!isNullBlank((String)resultMap.get(DEBIT_PREPAID_TYPE))){
			// デビット・プリペイド判定結果を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_DEBIT_PREPAID_TYPE, convertUtil.convertDebitPrepaidType());
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_DEBIT_PREPAID_TYPE, "");
		}
		
		// イシュア区分
		if(!isNullBlank((String)resultMap.get(ISSUR_CLASS))){
			// イシュア区分を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_ISSUR_CLASS, resultMap.get(ISSUR_CLASS));
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_ISSUR_CLASS, "");
		}
		
		// カードブランド
		if(!isNullBlank((String)resultMap.get(CARD_BRAND))){
			// イシュア区分を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_CARD_BRAND, convertUtil.convertCardBrand());
		} else {
			// ""(空)を設定
			inCBSMsg.set(EKKA0010003CBSMsg.PY_CARD_BRAND, "");
		}
		
		return;
	}
	
	/**
	 * null又は空文字の場合、trueを返却する
	 * 
	 * @param str 検査対象文字列
	 * @return true:null、又は空文字／false:左記以外
	 */
	public static boolean isNullBlank(String str)
	{
		if (null == str || "".equals(str))
		{
			return true;
		}
		return false;
	}
	
	/**
	 * ペイジェントからの返却結果をログに出力するため編集を行う
	 * 編集内容
	 *   マスクされたカード番号の場合はマスキング処理を行う
	 * @param resultMap ペイジェントからの返却結果
	 * @return ログ出力用文字列
	 */
	private String makeLogStr(HashMap<String,String> resultMap){
		
		//ログ用文字列組み立て用の変数を宣言する
		StringBuilder sb = new StringBuilder();
		
		//取得したkeyの件数分ループを行う
		for (String key : resultMap.keySet()) {
			
			//keyを元にvalueを取得する
			String value = (String)resultMap.get(key);
			
			//keyがマスクされたカード番号の場合、valueをマスキングする
			if(MASKED_CARD_NUMBER.equals(key)){
				value = "***";
			}
			
			//カード番号以外の場合は、返却結果のそのまま出力する
			sb.append(key + "=" + value + ",");
			
		}
	
		return sb.toString();
	}
}
