package com.unionpay.acp.demo;

import com.unionpay.acp.sdk.*;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

/**
 * 重要：联调测试时请仔细阅读注释！
 * <p>
 * 产品：签约支付产品<br>
 * 交易：交易状态查询交易<br>
 * 版权： 中国银联<br>
 * 声明：以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己需要，按照技术文档编写。该代码仅供参考，不提供编码，性能，规范性等方面的保障<br>
 */

public class Form36_16_TransStatusQuery {

    private final static Logger logger = Logger.getLogger(Form36_16_TransStatusQuery.class);

    public static void main(String[] args) {

        Map<String, String> contentData = new HashMap<String, String>();

        /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
        contentData.put("version", DemoBase.version);           //版本号
        contentData.put("encoding", DemoBase.encoding);         //字符集编码 可以使用UTF-8,GBK两种方式
        contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法
        contentData.put("txnType", "00");               //交易类型
        contentData.put("txnSubType", "00");            //交易子类
        contentData.put("bizType", "000000");           //产品类型 000000

        contentData.put("accessType", SDKConfig.getValueFromConfig("accessType"));
        if ("1".equals(SDKConfig.getValueFromConfig("accessType"))) {
            contentData.put("acqInsCode", SDKConfig.getValueFromConfig("acqInsCode"));//接入类型为收单机构接入时需上送
        }

        contentData.put("merId", SDKConfig.getValueFromConfig("merId"));
        contentData.put("orderId", SDKConfig.getValueFromConfig("orderId")); // 商户订单号，8-40位数字字母，不能含“-”或“_”，每次发交易测试需修改为被查询的交易的订单号
        contentData.put("txnTime", SDKConfig.getValueFromConfig("txnTime")); // 订单发送时间，格式为YYYYMMDDhhmmss，每次发交易测试需修改为被查询的交易的订单发送时间
        contentData.put("reserved", SDKConfig.getValueFromConfig("reserved"));//可选上送

        /**对请求参数进行签名并发送http post请求，接收同步应答报文**/
        String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl();                     //交易请求url从配置文件读取对应属性文件acp_sdk.properties中的acpsdk.batchTransUrl
        Map<String, String> reqData = AcpService.sign(contentData, DemoBase.encoding);                    //报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可
        //如果这里通讯读超时（30秒），需发起交易状态查询交易
        Map<String, String> rspData = AcpService.post(reqData, requestBackUrl, DemoBase.encoding);   //发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过

        //应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规范-第5部分-附录》
        if (!rspData.isEmpty()) {
            if (AcpService.validate(rspData, DemoBase.encoding)) {
                logger.info("验证签名成功");
                if (("00").equals(rspData.get("respCode"))) {//如果查询交易成功
                    String origRespCode = rspData.get("origRespCode");
                    //处理被查询交易的应答码逻辑
                    if (("00").equals(origRespCode) || ("A6").equals(origRespCode)) {
                        //A6贷记交易返回，参与清算，商户应该算成功交易，根据成功的逻辑处理
                        //交易成功，更新商户订单状态
                        //TODO
                    } else if (("03").equals(origRespCode) ||
                            ("04").equals(origRespCode) ||
                            ("05").equals(origRespCode) ||
                            ("01").equals(origRespCode) ||
                            ("12").equals(origRespCode) ||
                            ("34").equals(origRespCode) ||
                            ("60").equals(origRespCode)) {
                        //订单处理中或交易状态未明，需稍后发起交易状态查询交易 【如果最终尚未确定交易是否成功请以对账文件为准】
                        logger.warn("请稍后查询");
                    } else {
                        //其他应答码为交易失败
                        logger.warn("失败：" + rspData.get("respMsg"));
                    }
                } else if (("34").equals(rspData.get("respCode"))) {
                    //订单不存在，可认为交易状态未明，需要稍后发起交易状态查询，或依据对账结果为准

                } else {//查询交易本身失败，如应答码10/11检查查询报文是否正确
                    //TODO
                }
            } else {
                logger.error("验证签名失败");
                //TODO 检查验证签名失败的原因
            }
        } else {
            //未返回正确的http状态
            logger.error("未获取到返回报文或返回http状态码非200");
        }
    }


}
