<?php


namespace Modules\Wechat\Services;


use EasyWeChat\Pay\Application;
use Illuminate\Support\Facades\Config;
use Modules\Wechat\Utils\AesUtil;
use Modules\Wechat\Utils\WechatUtil;

class TransferService
{

	/**
	 * 商家转账到零钱
	 * @param $batch_name
	 * @param $out_trade_no
	 * @param $money
	 * @param $openid
	 * @throws BaseException
	 */
	public static function transfer($batch_name, $out_trade_no, $money, $openid,$body='用户提现')
	{
		$config = Config::get('wechat.miniapp');

		$app = new Application($config);

		//获取微信支付平台证书序列号
		$certificates=self::getCertificates();
		$serial_no = isset($certificates['data'][0]['serial_no'])?$certificates['data'][0]['serial_no']:null;

		$pars = [];
		$pars['appid'] = $config['app_id'];//直连商户的appid
		$pars['out_batch_no'] = 'batch' . date('Ymd') . mt_rand(1000, 9999);//商户系统内部的商家批次单号，要求此参数只能由数字、大小写字母组成，在商户系统内部唯一
		$pars['batch_name'] = $body;//该笔批量转账的名称
		$pars['batch_remark'] = $body;//转账说明，UTF8编码，最多允许32个字符
		$pars['total_amount'] = intval($money * 100);//转账总金额 单位为“分”
		$pars['total_num'] = 1;//转账总笔数
		$pars['transfer_detail_list'][0] = [
			'out_detail_no' => $out_trade_no,
			'transfer_amount' => $pars['total_amount'],
			'transfer_remark' => $body,
			'openid' => $openid,
			'user_name'=> WechatUtil::getEncrypt($batch_name,$config['public_key']),
		];//转账明细列表
		$pars['notify_url'] = request()->root() .'/api/wechat/notify/transfer';


		$result = $app->getClient()->postJson("v3/transfer/batches",$pars,[
			'headers'=>[
				'Wechatpay-Serial' => $serial_no,
			],
		]);

		$response = json_decode($result, true);

		if (!isset($response['create_time'])) { //批次受理失败
			return ['code'=>$response['code'],'message'=>$response['message']];
		}

		return $response['out_batch_no'];
	}

	//获取微信支付平台证书序列号与生成公钥文件
	public static function getCertificates($http_method ="GET"){

		$url="https://api.mch.weixin.qq.com/v3/certificates";

		$config = Config::get('wechat.miniapp');

		$token=WechatUtil::getToken($url, $http_method, array(),$config['mch_id'],$config['certificate'],$config['private_key']);

		$result = WechatUtil::https_request_transfer($url,array(),$token);

		$result_arr = json_decode($result,true);
		if(isset($result_arr['data'])){
			$certificate=$result_arr['data'][0]['encrypt_certificate'];
			$AesUtil = new AesUtil($config['secret_key']);
			$dataDecrypt=$AesUtil->decryptToString($certificate['associated_data'],$certificate['nonce'],$certificate['ciphertext']);
			$publicCertKey=fopen($config['public_key'], 'w');
			fwrite($publicCertKey, $dataDecrypt);
			fclose($publicCertKey);
		}
		return $result_arr;
	}


	/**查询商家转账到零钱订单状态
	 * @param $out_batch_no
	 * @param $out_detail_no
	 * @param string $http_method
	 * @return array|mixed
	 */
	public static function transferQuery($out_batch_no,$out_detail_no,$http_method ="GET")
	{
		$url = 'https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/'.$out_batch_no.'/details/out-detail-no/'.$out_detail_no;

		$config = Config::get('wechat.miniapp');

		$token=WechatUtil::getToken($url, $http_method, array(),$config['mch_id'],$config['certificate'],$config['private_key']);

		$result = WechatUtil::https_request_transfer($url,array(),$token);

		$result_arr = json_decode($result,true);

		if(isset($result_arr['code']) && !empty($result_arr['code'])){

			return ['code'=>-3,'message'=>$result_arr['message'],'fail_reason'=>$result_arr['code']];

		}else if(isset($result_arr['fail_reason']) && !empty($result_arr['fail_reason'])){

			if($result_arr['fail_reason'] === "ACCOUNT_FROZEN"){

				return ['code'=>-3,'message'=>"该用户账户被冻结",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "REAL_NAME_CHECK_FAIL"){

				return ['code'=>-3,'message'=>"收款人未实名认证，需要用户完成微信实名认证",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "NAME_NOT_CORRECT"){

				return ['code'=>-3,'message'=>"收款人姓名校验不通过，请核实信息",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "OPENID_INVALID"){

				return ['code'=>-3,'message'=>"Openid格式错误或者不属于商家公众账号",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "TRANSFER_QUOTA_EXCEED"){

				return ['code'=>-3,'message'=>"超过用户单笔收款额度，核实产品设置是否准确",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "DAY_RECEIVED_QUOTA_EXCEED"){

				return ['code'=>-3,'message'=>"超过用户单日收款额度，核实产品设置是否准确",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "DAY_RECEIVED_COUNT_EXCEED"){

				return ['code'=>-3,'message'=>"超过用户单日收款次数，核实产品设置是否准确",'fail_reason'=>$result_arr['code']];

			}else if($result_arr['fail_reason'] === "TRANSFER_RISK"){

				return ['code'=>-3,'message'=>"该笔转账可能存在风险，已被微信拦截",'fail_reason'=>$result_arr['code']];

			}else {
				return ['code'=>-3,'message'=>$result_arr['fail_reason'],'fail_reason'=>$result_arr['code']];
			}
		}

		return true;

	}
}