package com.crm.pay.service.impl.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.pay.dao.repository.CustomInfoRepository;
import com.crm.pay.dto.finance.withdraw.automatic.FinanceWithdrawPaymentasiaDto;
import com.crm.pay.entity.callback.PaymentasiaCallbackEntity;
import com.crm.pay.entity.callback.PaymentasiaPayoutCallbackEntity;
import com.crm.pay.entity.property.PaymentasiaPropertyEntity;
import com.crm.pay.entity.property.PaymentasiaWithdrawPropertyEntity;
import com.crm.pay.service.FinanceDepositService;
import com.crm.pay.service.PaymentasiaService;
import com.crm.pay.service.impl.base.BasePayServiceImpl;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.dto.finance.withdraw.FinanceWithdrawDto;
import com.crm.rely.backend.model.entity.custom.info.CustomInfoEntity;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositAddEntity;
import com.crm.pay.entity.FinanceDepositCallbackUpdateEntity;
import com.crm.pay.entity.finance.withdraw.FinanceWithdrawApproveChannelEntity;
import com.crm.pay.entity.finance.withdraw.FinanceWithdrawApproveChannelSubmitEntity;
import com.crm.pay.entity.finance.withdraw.automatic.FinanceWithdrawInfoEntity;
import com.crm.pay.entity.finance.withdraw.automatic.FinanceWithdrawPaymentasiaEntity;
import com.crm.rely.backend.core.exception.PayValidatedException;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.model.pojo.table.FinanceDepositTable;
import com.crm.rely.backend.model.pojo.table.SysRemitChannelTable;
import com.crm.rely.backend.model.pojo.table.SysRemittanceChannelTable;
import com.crm.rely.backend.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: houn
 * @create: 2023-06-14 12:45
 */
@Slf4j
@Service
public class PaymentasiaServiceImpl extends BasePayServiceImpl implements PaymentasiaService {

    @Autowired
    private FinanceDepositService financeDepositService;

    @Autowired
    private CustomInfoRepository customInfoRepository;

    /**
     * help通道支付业务逻辑 包括加密 汇率等
     *
     * @param balanceSaveEntity 支付实体
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String pay(FinanceDepositAddEntity balanceSaveEntity, CustomInfoEntity infoEntity) throws Exception {
        SysRemittanceChannelTable channel = getPayChannel(balanceSaveEntity.getPayType());

        PaymentasiaPropertyEntity payProperty = getPayProperty(channel, PaymentasiaPropertyEntity.class);

        balanceSaveEntity.setCurrency(channel.getCurrency());
        balanceSaveEntity.setTransformCurrency(channel.getTransformCurrency());

        FinanceDepositTable financeDepositTable = financeDepositService.save(balanceSaveEntity, channel);

        //获取form表单数据
        String formString = getForm(payProperty, financeDepositTable, balanceSaveEntity, infoEntity);

        //将form字符串加入到实体
        financeDepositTable.setFormUrl(formString);
        
        return financeDepositTable.getSerial();
    }

    /**
     * 回调处理数据
     *
     * @param callbackEntity
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void callback(PaymentasiaCallbackEntity callbackEntity) throws Exception {
        log.info(String.format("callback orderNo:%s,callback data:%s", callbackEntity.getMerchant_reference(),
                JSON.toJSONString(callbackEntity)));

        boolean flag = validate(callbackEntity);
        if (!flag) {
            throw new ServiceException("fail");
        }

        FinanceDepositCallbackUpdateEntity balanceCallbackUpdateEntity =
                getFinanceDepositCallbackUpdateEntity(PayConstants.PAYMENTASIA_SUCCESS_STATUS,
                        callbackEntity.getMerchant_reference(),
                        callbackEntity.getRequest_reference(),
                        callbackEntity.getStatus(),
                        callbackEntity);
        balanceCallbackUpdateEntity.setTransformAmount(new BigDecimal(callbackEntity.getAmount()));
        /**
         * 更新数据
         */
        financeDepositService.updateCallback(balanceCallbackUpdateEntity);
    }

    @Override
    public FinanceWithdrawPaymentasiaDto withdrawInfo(FinanceWithdrawInfoEntity entity) throws Exception {
        FinanceWithdrawDto withdrawDto = null;
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            withdrawDto = financeWithdrawService.searchSingle(entity.getId());
        } else {
            //withdrawDto = financeAgentWithdrawService.searchSingle(entity.getId());
        }
        entity.setPayType(PayConstants.PAYMENTASIA_PAY_TYPE_REMIT);

        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(withdrawDto.getCustomId());
        SysRemitChannelTable withdrawChannel = getWithdrawChannel(entity.getPayType());

        FinanceWithdrawPaymentasiaDto dto = new FinanceWithdrawPaymentasiaDto();
        dto.setBeneficiaryName(withdrawDto.getName());
        dto.setBeneficiaryFirstName(customInfoTable.getFirstName());
        dto.setBeneficiaryLastName(customInfoTable.getLastName());
        dto.setBankName(withdrawDto.getBankName());
        dto.setBeneficiaryEmail(customInfoTable.getEmail());
        dto.setBeneficiaryCity(customInfoTable.getCity());
        dto.setBeneficiaryPhone(customInfoTable.getPhone());
        dto.setBeneficiaryIdentityCard(customInfoTable.getIdentity());
        dto.setAccountNumber(withdrawDto.getBankCardNum());
        dto.setCurrency(withdrawDto.getBankCode());
        dto.setAmount(withdrawDto.getTransformAmount() == null ? null :
                withdrawDto.getTransformAmount().setScale(2, BigDecimal.ROUND_DOWN));

        dto.setId(withdrawDto.getId());
        dto.setSerial(withdrawDto.getSerial());
        dto.setWithdrawUrl(withdrawChannel.getWithdrawUrl());
        dto.setPayType(entity.getPayType());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void withdraw(FinanceWithdrawPaymentasiaEntity entity) throws Exception {
        FinanceWithdrawDto withdrawDto = null;
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            withdrawDto = financeWithdrawService.searchSingle(entity.getId());
        } else {
            //withdrawDto = financeAgentWithdrawService.searchSingle(entity.getId());
        }
        entity.setCId(withdrawDto.getCId());
        entity.setSerial(withdrawDto.getSerial());
        entity.setLogin(withdrawDto.getLogin());

        PaymentasiaWithdrawPropertyEntity withdrawProperty = getWithdrawProperty(PayConstants.PAYMENTASIA_PAY_TYPE_REMIT, PaymentasiaWithdrawPropertyEntity.class);

        payout(entity, withdrawProperty);

        FinanceWithdrawApproveChannelSubmitEntity financeWithdrawApproveChannelSubmitEntity =
                new FinanceWithdrawApproveChannelSubmitEntity();
        financeWithdrawApproveChannelSubmitEntity.setSubmitStatus(PayConstants.PASSED_STATUS);
        financeWithdrawApproveChannelSubmitEntity.setId(entity.getId());
        financeWithdrawApproveChannelSubmitEntity.setActualPayType(entity.getPayType());
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            financeWithdrawService.approve(financeWithdrawApproveChannelSubmitEntity);
        } else {
            //financeAgentWithdrawService.approve(financeWithdrawApproveChannelSubmitEntity);
        }
    }

    private void payout(FinanceWithdrawPaymentasiaEntity entity, PaymentasiaWithdrawPropertyEntity propertyEntity) throws Exception {
        log.info(String.format("payout json:%s",JSON.toJSON(entity)));

        String secretCode = propertyEntity.getSecretCode(); // 密钥
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("request_reference",entity.getSerial());
        paramMap.put("beneficiary_name",URLEncoder.encode(entity.getBeneficiaryName(),"UTF-8"));
        paramMap.put("beneficiary_first_name",URLEncoder.encode(entity.getBeneficiaryFirstName(),"UTF-8"));
        paramMap.put("beneficiary_last_name",URLEncoder.encode(entity.getBeneficiaryLastName(),"UTF-8"));
        paramMap.put("bank_name",URLEncoder.encode(entity.getBankName(),"UTF-8"));
        paramMap.put("beneficiary_email",entity.getBeneficiaryEmail());
        paramMap.put("beneficiary_city",StringUtils.isNotEmpty(entity.getBeneficiaryCity())? "": URLEncoder.encode(entity.getBeneficiaryCity(),"UTF-8"));
        paramMap.put("beneficiary_phone",entity.getBeneficiaryPhone());
        paramMap.put("beneficiary_identity_card", StringUtils.isNotEmpty(entity.getBeneficiaryIdentityCard())?"":entity.getBeneficiaryIdentityCard());
        paramMap.put("account_number",entity.getAccountNumber());
        paramMap.put("currency",entity.getCurrency());
        paramMap.put("amount", String.format("%.2f", entity.getAmount().doubleValue()));
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            paramMap.put("datafeed_url", propertyEntity.getNotifyUrl());
        } else {
            paramMap.put("datafeed_url", propertyEntity.getAgentNotifyUrl());
        }

        String signString = MapUtil.getStringSortByKey(paramMap) + secretCode;

        String sign;
        try {
            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
        } catch (Exception e) {
            sign = null;
        }
        String url = String.format(propertyEntity.getBaseUrl() + propertyEntity.getPayoutUrl(),
                propertyEntity.getMerchantToken());

        paramMap.put("sign",sign);
        Map<String, String> headers = new HashMap<>(1);
        headers.put("Content-Type", "application/x-www-form-urlencoded");

        Connection.Response response = HttpUtil.post(headers,url,paramMap);
        log.info(String.format("url:%s,json:%s,body:%s", url, JSON.toJSON(paramMap), response.body()));

        JSONObject jsonObject = JSON.parseObject(response.body());
        log.info("Paymentasia payout response body:" + response.body());

        if (response.statusCode() != 200 || jsonObject == null) {
            throw new PayValidatedException("Payment platform is abnormal, please try again later or contact customer service.");
        }

        if ("400".equals(jsonObject.getJSONObject("response").getString("code"))){
            String message = jsonObject.getJSONObject("response").getString("message");
            if (StringUtils.isNotEmpty(message)){
                throw new PayValidatedException(message);
            }
            throw new PayValidatedException("Payment platform is abnormal, please try again later or contact customer service.");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String withdrawCallback(Integer withdrawType, PaymentasiaPayoutCallbackEntity callbackEntity) throws Exception {
        log.info(String.format("callback data:%s", callbackEntity));

        PaymentasiaWithdrawPropertyEntity withdrawProperty = getWithdrawProperty(PayConstants.PAYMENTASIA_PAY_TYPE_REMIT, PaymentasiaWithdrawPropertyEntity.class);
        // 验证签名
        boolean flag = this.validateWithdrawSign(callbackEntity, withdrawProperty.getSecretCode());
        if (!flag || !queryValidateWithdrawOrderInfo(callbackEntity)){
            log.error("Paymentasia withdraw callback verification signature error");
            return Constants.FAIL;
        }
        String status = callbackEntity.getStatus();
        String requestReference = callbackEntity.getRequestReference();
        String token = callbackEntity.getToken();

        log.info("Paymentasia withdraw callback--Status:"+status+", requestReference:"+requestReference+", token:"+token);

        FinanceWithdrawApproveChannelEntity financeWithdrawApproveChannelEntity =
                new FinanceWithdrawApproveChannelEntity();
        financeWithdrawApproveChannelEntity.setChannelSerial(token);

        // 状态 0-待处理 1-成功 2-失败 3-批准 4-处理中 8-取消
        if (!"1".equals(status)) {
            financeWithdrawApproveChannelEntity.setCallbackStatus(PayConstants.CALLBACE_FAIL_STATUS);
        } else {
            financeWithdrawApproveChannelEntity.setCallbackStatus(PayConstants.CALLBACE_SUCCESS_STATUS);
        }
        financeWithdrawApproveChannelEntity.setSerial(requestReference);

        /**
         * 更新数据
         */
        if (withdrawType == null || withdrawType.equals(1)) {
            financeWithdrawService.approve(financeWithdrawApproveChannelEntity);
        } else {
            //financeAgentWithdrawService.channel(financeWithdrawApproveChannelEntity);
        }

        return PayConstants.STIC_SUCCESS_RESULT;

    }


    private boolean queryValidateWithdrawOrderInfo(PaymentasiaPayoutCallbackEntity callbackEntity) throws IOException, ServiceException {
        PaymentasiaWithdrawPropertyEntity withdrawProperty = getWithdrawProperty(PayConstants.PAYMENTASIA_PAY_TYPE_REMIT, PaymentasiaWithdrawPropertyEntity.class);


        String secretCode = withdrawProperty.getSecretCode(); // 密钥
        Map<String,String> params = new HashMap<>();
        params.put("request_reference",callbackEntity.getRequestReference());
        String signString = MapUtil.getStringSortByKey(params) + secretCode;

        String sign;
        try {
            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
        } catch (Exception e) {
            sign = null;
        }
        String queryUrl = String.format(withdrawProperty.getBaseUrl() + withdrawProperty.getQueryUrl(),
                withdrawProperty.getMerchantToken());

        params.put("sign",sign);
        Map<String, String> headers = new HashMap<>(1);
        headers.put("Content-Type", "application/x-www-form-urlencoded");

        log.info(String.format("paymentasia get order info url:%s,headers:%s,data:%s", queryUrl, JSON.toJSONString(headers),
                JSON.toJSONString(params)));
        Connection.Response response = HttpUtil.post(headers,queryUrl,params);

        String payString = response.body();

        log.info(String.format("paymentasia get order info:%s", payString));

        JSONObject jsonObject = JSON.parseObject(payString);
        if (!jsonObject.getJSONObject("response").getString("code").equals(PayConstants.PAYMENTASIA_PAY_TYPE_SUCCESS_STATUS)) {
            return false;
        }
        return true;
    }


    /**
     * 获取支付form
     *
     * @param financeDepositTable
     * @return
     * @throws ServiceException
     */
    private String getForm(PaymentasiaPropertyEntity propertyEntity, FinanceDepositTable financeDepositTable,
                           FinanceDepositAddEntity balanceSaveEntity, CustomInfoEntity infoEntity) throws ServiceException,
            IOException {

        Map<String, String> map = new HashMap<>(10);
        map.put("merchant_reference", financeDepositTable.getSerial() + "_" + financeDepositTable.getLogin());
        map.put("currency", financeDepositTable.getTransformCurrency());
        map.put("amount", String.format("%.2f", financeDepositTable.getTransformAmount().doubleValue()));
        map.put("return_url", propertyEntity.getReturnUrl());
        map.put("customer_ip", balanceSaveEntity.getIp());
        map.put("customer_first_name", infoEntity.getFirstName());
        map.put("customer_last_name", infoEntity.getLastName());
        map.put("customer_phone", infoEntity.getPhone());
        map.put("customer_email", infoEntity.getEmail());
        map.put("network", "DirectDebit");

        String sign = getPaySign(propertyEntity, map);

        map.put("sign", sign);

        String url = String.format(propertyEntity.getBaseUrl() + propertyEntity.getPaymentUrl(),
                propertyEntity.getMerchantToken());

        String formString = PayFormUtil.getForm(url, map);

        log.info(String.format("支付请求,请求orderNo:%s,请求form:%s", financeDepositTable.getSerial(), formString));

        return formString;
    }

    /**
     * 验证回调参数是否被篡改
     *
     * @param callbackEntity
     * @return
     * @throws ServiceException
     */
    private boolean validate(PaymentasiaCallbackEntity callbackEntity) throws Exception {

        Map<String, String> params = new HashMap<>(10);
        params.put("merchant_reference", callbackEntity.getMerchant_reference());
        params.put("request_reference", callbackEntity.getRequest_reference());
        params.put("currency", callbackEntity.getCurrency());
        params.put("amount", callbackEntity.getAmount());
        params.put("status", callbackEntity.getStatus());
        String sign = getCallbackSign(params);
        return callbackEntity.getSign().equals(sign);
    }

    private String getCallbackSign(Map<String, String> params) throws Exception {

        PaymentasiaPropertyEntity propertyEntity = getPayProperty(PayConstants.PAYMENTASIA_PAY,
                PaymentasiaPropertyEntity.class);
        String signString = MapUtil.getStringSortByKey(params) + propertyEntity.getSecretCode();

        String sign;
        try {
            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
        } catch (Exception e) {
            sign = null;
        }

        log.info(String.format("paymentasia--orderNo:%s,sign string:%s,sign:%s", params.get(
                        "merchant_reference"), signString,
                sign));

        return sign;
    }

    private String getPaySign(PaymentasiaPropertyEntity propertyEntity, Map<String, String> params) throws UnsupportedEncodingException {

        Map<String, String> map = new HashMap<>(10);
        map.put("merchant_reference", params.get("merchant_reference"));
        map.put("currency", params.get("currency"));
        map.put("amount", params.get("amount"));
        map.put("return_url", URLEncoder.encode(params.get("return_url"), "UTF-8"));
        map.put("customer_ip", params.get("customer_ip"));
        map.put("customer_first_name", URLEncoder.encode(params.get("customer_first_name"), "UTF-8"));
        map.put("customer_last_name", URLEncoder.encode(params.get("customer_last_name"), "UTF-8"));
        map.put("customer_phone", params.get("customer_phone"));
        map.put("customer_email", URLEncoder.encode(params.get("customer_email"), "UTF-8"));
        map.put("network", params.get("network"));

        String signString = MapUtil.getStringSortByKey(map) + propertyEntity.getSecretCode();

        String sign;
        try {
            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
        } catch (Exception e) {
            sign = null;
        }


        log.info(String.format("paymentasia--orderNo:%s,sign string:%s,sign:%s", params.get(
                        "merchant_reference"), signString,
                sign));

        return sign;
    }


    public boolean validateWithdrawSign(PaymentasiaPayoutCallbackEntity callbackEntity,String secretCode) throws ServiceException {
        String _sign = callbackEntity.getSign();
        Map<String, String> params = new HashMap<>(12);
        if (StringUtils.isNotEmpty(callbackEntity.getBatchReference())){
            params.put("batch_reference", callbackEntity.getBatchReference());
        }
        params.put("request_reference", callbackEntity.getRequestReference());
        params.put("token", callbackEntity.getToken());
        params.put("beneficiary_name", callbackEntity.getBeneficiaryName());
        params.put("bank_name", callbackEntity.getBankName());
        params.put("account_number", callbackEntity.getAccountNumber());
        params.put("order_currency", callbackEntity.getOrderCurrency());
        params.put("order_amount", callbackEntity.getOrderAmount());
        params.put("status", callbackEntity.getStatus());
        params.put("fail_reason", StringUtils.isNotEmpty(callbackEntity.getFailReason())?"":callbackEntity.getFailReason());
        params.put("created_time", String.valueOf(callbackEntity.getCreatedTime()));
        params.put("completed_time", callbackEntity.getCompletedTime()!= null?"":String.valueOf(callbackEntity.getCompletedTime()));

        String signString = MapUtil.getStringSortByKey(params) + secretCode;

        String sign;
        try {
            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
        } catch (Exception e) {
            sign = null;
        }

        log.info(String.format("paymentasia--orderNo:%s,sign string:%s,sign:%s", params.get(
                        "request_reference"), signString,
                sign));

        return _sign.equals(sign);
    }

    public static void main1(String[] args) {
        String s  = "yi/5CoioHqnlpsoejjQW57E59eWnnPCE3FI5g/fzalV4cMYSyyYw9Laq+YFBs7+JxYx/N4CFqdiB1VJJmwuFtQmBsn5d5rmOkF/QezSgTysWrwSn6Jxf42SaRmB2ohaMMMa7ZSbyKFfiPY7jppiierVQZw/n29ViWEFDjQjEebGf5C4oRcmTuqTr+vlaLrkMpXyjw2FvktzeoDgOE3UxCW0mgZjxfRnbtVkFC9tlLNnk3rKzypFV2/ea6GLZw8bEG4qNbE6yItZkzlWYDZXnBhBUs9P4B/DaBHgkao5WtgLJnSoDH9iC+Z2m24n8WPsj6Xs9U9yJQIZcIrcT18H3kesfvGC/QxJTScMqfme3GzFUQE0eCOl30W8nDjKwJyEOezNHqQ168eXajB7FIONFOFIbGHOD9ZNWV51uaCgK4uPmFT03yKZMPUwOBoOEYAbg3uTOHNUy9+BqdmY/5ttf1Q==";
        System.out.println(AESUtil.decrypt(s, "bfa5559109f94c78af615bcf00d52060"));
    }
    public static void main(String[] args) throws Exception {

        FinanceWithdrawDto balanceTable = new FinanceWithdrawDto();


//        String secret = "127f7830-b856-4ddf-92b4-a6478e38547b";
//        //
//        Map<String, String> params = new HashMap<>(10);
//        params.put("merchant_reference", "1234567890");
//        params.put("currency", "THB");
//        params.put("amount", "600.00");
//        params.put("customer_ip", "123.123.123.123");
//        params.put("customer_first_name", "John");
//        params.put("customer_last_name", "Doe");
//        params.put("customer_address", URLEncoder.encode("1, Bay Street", "UTF-8"));
//        params.put("customer_phone", "0123123123");
//        params.put("customer_email", URLEncoder.encode("someone@gmail.com", "UTF-8"));
//        params.put("return_url", URLEncoder.encode("https://demo.shop.com/payment/return", "UTF-8"));
//        params.put("network", "DirectDebit");
//
//        //amount=600.00&currency=THB&customer_address=1%2C+Bay+Street&customer_email=someone%40gmail
//        // .com&customer_first_name=John&customer_ip=123.123.123
//        // .123&customer_last_name=Doe&customer_phone=0123123123&merchant_reference=1234567890&network=DirectDebit
//        // &return_url=https%3A%2F%2Fdemo.shop.com%2Fpayment%2Freturn127f7830-b856-4ddf-92b4-a6478e38547b
//
//        //amount=600.00&currency=THB&customer_address=1%2C+Bay+Street&customer_email=someone@gmail
//        // .com&customer_first_name=John&customer_ip=123.123.123
//        // .123&customer_last_name=Doe&customer_phone=0123123123&merchant_reference=1234567890&network=DirectDebit
//        // &return_url=https%3A%2F%2Fdemo.shop.com%2Fpayment%2Freturn127f7830-b856-4ddf-92b4-a6478e38547b
//        String signString = MapUtil.getStringSortByKey(params) + secret;
//
//        System.out.println(signString);
//        String sign;
//        try {
//            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
//        } catch (Exception e) {
//            sign = null;
//        }
//
//        System.out.println(sign);
//        System.out.println(AESUtil.encrypt("{\n" +
//                "    \"merchantId\": \"2023-CWGMARKETSAB\",\n" +
//                "    \"merchantToken\": \"dbea33ec-9834-4fd7-980e-24cb9ee5f0b5\",\n" +
//                "    \"secretCode\": \"b4694938-55aa-4429-8a5f-c21481c2eeea\",\n" +
//                "    \"returnUrl\": \"http://8.210.194.53:8004/paymentasia/pickup\",\n" +
//                "    \"baseUrl\": \"https://payment.pa-sys.com\",\n" +
//                "    \"paymentUrl\": \"/app/page/%s\",\n" +
//                "    \"queryUrl\": \"/%s/payment/query\"\n" +
//                "}", "bfa5559109f94c78af615bcf00d52060"));
        String con = "{\n" +
                "    \"merchantToken\": \"dbea33ec-9834-4fd7-980e-24cb9ee5f0b5\",\n" +
                "    \"secretCode\": \"b4694938-55aa-4429-8a5f-c21481c2eeea\",\n" +
                "    \"notifyUrl\": \"https://testpay.cwgvu.com/paymentasia/withdraw/callback\",\n" +
                "    \"agentNotifyUrl\": \"https://testpay.cwgvu.com/paymentasia/agent/withdraw/callback\",\n" +
                "    \"baseUrl\": \"https://payment.pa-sys.com\",\n" +
                "    \"payoutUrl\": \"/%s/payout/v1/request\",\n" +
                "    \"queryUrl\": \"/%s/payout/v1/query\"\n" +
                "}";
//        System.out.println(AESUtil.encrypt(con,"bfa5559109f94c78af615bcf00d52060"));

        String decrypt = AESUtil.decrypt("UvlzE/FZCroO6HMEpUdKV3D5kEQBGiXMp3dK/ZJQUhUHMP1npkRN9pkmWs455e2ADyESS9x1VFttLPo/UeBuxbhSro64NXe4a+2G3tZeGKRQB+MHicBYxx55qZtbrQqUM2eMRvZQDe2EOh9bpu1E5bc634k+my5e6SjD6hyUAfLdEfHjFdT4h3h16g3KogG0myU9hmHTPHPoQcOcu70Y4+t6XCixyGGxAyVVgIKcffFwaFHrFE/9mKiT7RJiKDFfKHMMmve5BW6Je3bTiNTc5+ZfVDt29r1Vkl1NGIN+Xl9wdGlfrKHcu45SadR3w27ecBhNAmiH+yo1fJKUtastfC8r1vOAvD5mFYtPXuZscw+DsGr7B1YdwA5OkqjjMl7ZI0fz74jsBo6Rl581Rr2lvZJT5XAK8Pg2pbfjebU9LVaHwlvi7bVZwtVrgd8o0YFO5tCV9e/L9Ii0eyR0kvCqSd/ABt0sJ948Gen7q7QKBQ9gIzm/ShXAg98YcD8gL6TO", "bfa5559109f94c78af615bcf00d52060");
//        System.out.println(decrypt);

        String secretCode = "b4694938-55aa-4429-8a5f-c21481c2eeea";
//        String secretCode = "0b4a15bb-6403-4887-9e18-f7a88d2502b0";

        String baseUrl = "https://gateway.pa-sys.com";
        String merchantToken = "dbea33ec-9834-4fd7-980e-24cb9ee5f0b5";
        String payoutUrl = "/%s/payout/v1/request";
        String url = String.format(baseUrl + payoutUrl , merchantToken);

        System.out.println("url: " + url);
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("request_reference","pa_1234567890");
        paramMap.put("beneficiary_name",URLEncoder.encode("chan tai man", "UTF-8"));
        paramMap.put("beneficiary_first_name",URLEncoder.encode("tai man", "UTF-8"));
        paramMap.put("beneficiary_last_name",URLEncoder.encode("chan", "UTF-8"));
        paramMap.put("bank_name","MAY");
        paramMap.put("beneficiary_email",URLEncoder.encode("chantaiman@paymentasia.com", "UTF-8"));
        paramMap.put("beneficiary_city","");
        paramMap.put("beneficiary_phone","85211111111");
        paramMap.put("beneficiary_identity_card","1234567890");
        paramMap.put("account_number","123456789012");
        paramMap.put("currency","MYR");
        paramMap.put("amount","14000.12");
        paramMap.put("datafeed_url",URLEncoder.encode("https://example.merchant-crm.site/payout/callback", "UTF-8"));

        String signString = MapUtil.getStringSortByKey(paramMap, false,true) + secretCode;
        System.out.println("signString: " + signString);

        String sign;
        try {
            sign = ShaUtil.sha(ShaUtil.SHA512, signString);
        } catch (Exception e) {
            sign = null;
        }
        System.out.println("sign: " + sign);
        paramMap.put("sign",sign);
        Map<String, String> headers = new HashMap<>(1);
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        System.out.println("paramMap:" + paramMap);
        System.out.println("headers:" + headers);
        Connection.Response response = HttpUtil.post(headers,url,paramMap);

        String payString = response.body();
        System.out.println("response body:" + payString);

    }
}
