Prechádzať zdrojové kódy

支付宝立减金查询API

lowkeyman 1 rok pred
rodič
commit
1e9511cb08

+ 382 - 0
data/api/alibank/client.php

@@ -0,0 +1,382 @@
+<?php
+namespace alibank;
+
+use aop\AopClient;
+use EncryptParseItem;
+use Log;
+use \SignData;
+
+class client extends AopClient
+{
+    private $RESPONSE_SUFFIX = "_response";
+    private $ERROR_RESPONSE = "error_response";
+    private $SIGN_NODE_NAME = "sign";
+    private $ENCRYPT_XML_NODE_NAME = "response_encrypted";
+    private $targetServiceUrl = "";
+
+    public function execute($request, $authToken = null, $appInfoAuthtoken = null, $targetAppId = null)
+    {
+
+        $this->setupCharsets($request);
+
+        //如果两者编码不一致,会出现签名验签或者乱码
+        if (strcasecmp($this->fileCharset, $this->postCharset)) {
+            throw new \Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!");
+        }
+
+        $iv = null;
+
+        if (!$this->checkEmpty($request->getApiVersion())) {
+            $iv = $request->getApiVersion();
+        } else {
+            $iv = $this->apiVersion;
+        }
+
+        //组装系统参数
+        $sysParams["app_id"] = $this->appId;
+        $sysParams["version"] = $iv;
+        $sysParams["format"] = $this->format;
+        $sysParams["sign_type"] = $this->signType;
+        $sysParams["method"] = $request->getApiMethodName();
+        $sysParams["timestamp"] = date("Y-m-d H:i:s");
+
+        if (!$this->checkEmpty($authToken)) {
+            $sysParams["auth_token"] = $authToken;
+        }
+        $sysParams["alipay_sdk"] = $this->alipaySdkVersion;
+        if (!$this->checkEmpty($request->getTerminalType())) {
+            $sysParams["terminal_type"] = $request->getTerminalType();
+        }
+        if (!$this->checkEmpty($request->getTerminalInfo())) {
+            $sysParams["terminal_info"] = $request->getTerminalInfo();
+        }
+        if (!$this->checkEmpty($request->getProdCode())) {
+            $sysParams["prod_code"] = $request->getProdCode();
+        }
+        if (!$this->checkEmpty($request->getNotifyUrl())) {
+            $sysParams["notify_url"] = $request->getNotifyUrl();
+        }
+        $sysParams["charset"] = $this->postCharset;
+        if (!$this->checkEmpty($appInfoAuthtoken)) {
+            $sysParams["app_auth_token"] = $appInfoAuthtoken;
+        }
+        if (!$this->checkEmpty($targetAppId)) {
+            $sysParams["target_app_id"] = $targetAppId;
+        }
+        if (!$this->checkEmpty($this->targetServiceUrl)) {
+            $sysParams["ws_service_url"] = $this->targetServiceUrl;
+        }
+
+        //获取业务参数
+        $apiParams = $request->getApiParas();
+
+        if (method_exists($request, "getNeedEncrypt") && $request->getNeedEncrypt()) {
+
+            $sysParams["encrypt_type"] = $this->encryptType;
+
+            if ($this->checkEmpty($apiParams['biz_content'])) {
+                throw new \Exception(" api request Fail! The reason : encrypt request is not supperted!");
+            }
+
+            if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) {
+                throw new \Exception(" encryptType and encryptKey must not null! ");
+            }
+
+            if ("AES" != $this->encryptType) {
+                throw new \Exception("加密类型只支持AES");
+            }
+
+            // 执行加密
+            $enCryptContent = encrypt::encrypt($apiParams['biz_content'], $this->encryptKey);
+            $apiParams['biz_content'] = $enCryptContent;
+        }
+
+        //签名
+        $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType);
+
+        //系统参数放入GET请求串
+        $requestUrl = $this->gatewayUrl . "?";
+        foreach ($sysParams as $sysParamKey => $sysParamValue) {
+            if ($sysParamValue != null) {
+                $requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&";
+            }
+        }
+        $requestUrl = substr($requestUrl, 0, -1);
+
+        //发起HTTP请求
+        try {
+            $resp = $this->curl($requestUrl, $apiParams);
+        } catch (\Exception $e) {
+            $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage());
+            return false;
+        }
+
+        //解析AOP返回结果
+        $respWellFormed = false;
+
+        // 将返回结果转换本地文件编码
+        $r = iconv($this->postCharset, $this->fileCharset, $resp);
+
+        $signData = null;
+        if ("json" == strtolower($this->format)) {
+            $respObject = json_decode($r);
+            if (null !== $respObject) {
+                $respWellFormed = true;
+                $signData = $this->parserJSONSignData($request, $resp, $respObject);
+            }
+        } else if ("xml" == $this->format) {
+            $disableLibxmlEntityLoader = libxml_disable_entity_loader(true);
+            $respObject = @ simplexml_load_string($resp);
+            if (false !== $respObject) {
+                $respWellFormed = true;
+
+                $signData = $this->parserXMLSignData($request, $resp);
+            }
+            libxml_disable_entity_loader($disableLibxmlEntityLoader);
+        }
+
+        //返回的HTTP文本不是标准JSON或者XML,记下错误日志
+        if (false === $respWellFormed) {
+            $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_RESPONSE_NOT_WELL_FORMED", $resp);
+            return false;
+        }
+
+        // 验签
+        $this->checkResponseSign($request, $signData, $resp, $respObject);
+
+        // 解密
+        if (method_exists($request, "getNeedEncrypt") && $request->getNeedEncrypt()) {
+            if ("json" == strtolower($this->format)) {
+
+                $resp = $this->encryptJSONSignSource($request, $resp);
+
+                // 将返回结果转换本地文件编码
+                $r = iconv($this->postCharset, $this->fileCharset, $resp);
+
+                $respObject = json_decode($r);
+            } else {
+
+                $resp = $this->encryptXMLSignSource($request, $resp);
+
+                $r = iconv($this->postCharset, $this->fileCharset, $resp);
+
+                $disableLibxmlEntityLoader = libxml_disable_entity_loader(true);
+                $respObject = @ simplexml_load_string($r);
+                libxml_disable_entity_loader($disableLibxmlEntityLoader);
+
+            }
+        }
+
+        return $respObject;
+    }
+
+    /**
+     * 验签
+     * @param $request
+     * @param $signData
+     * @param $resp
+     * @param $respObject
+     * @throws Exception
+     */
+    public function checkResponseSign($request, $signData, $resp, $respObject)
+    {
+
+        if (!$this->checkEmpty($this->alipayPublicKey) || !$this->checkEmpty($this->alipayrsaPublicKey)) {
+
+
+            if ($signData == null || $this->checkEmpty($signData->sign) || $this->checkEmpty($signData->signSourceData)) {
+
+                throw new \Exception(" check sign Fail! The reason : signData is Empty");
+            }
+
+
+            // 获取结果sub_code
+            $responseSubCode = $this->parserResponseSubCode($request, $resp, $respObject, $this->format);
+
+
+            if (!$this->checkEmpty($responseSubCode) || ($this->checkEmpty($responseSubCode) && !$this->checkEmpty($signData->sign))) {
+
+                $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType);
+
+
+                if (!$checkResult) {
+
+                    if (strpos($signData->signSourceData, "\\/") > 0) {
+
+                        $signData->signSourceData = str_replace("\\/", "/", $signData->signSourceData);
+
+                        $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType);
+
+                        if (!$checkResult) {
+                            throw new \Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]");
+                        }
+
+                    } else {
+
+                        throw new \Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]");
+                    }
+
+                }
+            }
+
+
+        }
+    }
+
+    private function setupCharsets($request)
+    {
+        if ($this->checkEmpty($this->postCharset)) {
+            $this->postCharset = 'UTF-8';
+        }
+        $str = preg_match('/[\x80-\xff]/', $this->appId) ? $this->appId : print_r($request, true);
+        $this->fileCharset = mb_detect_encoding($str, "UTF-8, GBK") == 'UTF-8' ? 'UTF-8' : 'GBK';
+    }
+
+    // 获取加密内容
+    private function encryptJSONSignSource($request, $responseContent)
+    {
+        $parsetItem = $this->parserEncryptJSONSignSource($request, $responseContent);
+
+        $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex);
+        $bodyEndContent = substr($responseContent, $parsetItem->endIndex,
+            strlen($responseContent) + 1 - $parsetItem->endIndex);
+
+        $bizContent = encrypt::decrypt($parsetItem->encryptContent, $this->encryptKey);
+        return $bodyIndexContent.$bizContent.$bodyEndContent;
+    }
+
+    public function decryptJSONSignSource($bizContent, $charset)
+    {
+        $bizContent = encrypt::decrypt($bizContent, $this->encryptKey);
+
+        $r = iconv($charset, 'UTF-8', $bizContent);
+        return json_decode($r);
+    }
+
+    private function encryptXMLSignSource($request, $responseContent)
+    {
+        $parsetItem = $this->parserEncryptXMLSignSource($request, $responseContent);
+
+        $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex);
+        $bodyEndContent = substr($responseContent, $parsetItem->endIndex,
+            strlen($responseContent) + 1 - $parsetItem->endIndex);
+        $bizContent = encrypt::decrypt($parsetItem->encryptContent, $this->encryptKey);
+
+        return $bodyIndexContent.$bizContent.$bodyEndContent;
+    }
+
+    private function parserEncryptXMLSignSource($request, $responseContent)
+    {
+        $apiName = $request->getApiMethodName();
+        $rootNodeName = str_replace(".", "_", $apiName).$this->RESPONSE_SUFFIX;
+
+        $rootIndex = strpos($responseContent, $rootNodeName);
+        $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE);
+
+        if ($rootIndex > 0) {
+            return $this->parserEncryptXMLItem($responseContent, $rootNodeName, $rootIndex);
+        } else {
+            if ($errorIndex > 0) {
+                return $this->parserEncryptXMLItem($responseContent, $this->ERROR_RESPONSE, $errorIndex);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    private function parserEncryptXMLItem($responseContent, $nodeName, $nodeIndex)
+    {
+        $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1;
+
+        $xmlStartNode = "<".$this->ENCRYPT_XML_NODE_NAME.">";
+        $xmlEndNode = "</".$this->ENCRYPT_XML_NODE_NAME.">";
+
+        $indexOfXmlNode = strpos($responseContent, $xmlEndNode);
+        if ($indexOfXmlNode < 0) {
+            $item = new EncryptParseItem();
+            $item->encryptContent = null;
+            $item->startIndex = 0;
+            $item->endIndex = 0;
+            return $item;
+        }
+
+        $startIndex = $signDataStartIndex + strlen($xmlStartNode);
+        $bizContentLen = $indexOfXmlNode - $startIndex;
+        $bizContent = substr($responseContent, $startIndex, $bizContentLen);
+
+        $encryptParseItem = new EncryptParseItem();
+        $encryptParseItem->encryptContent = $bizContent;
+        $encryptParseItem->startIndex = $signDataStartIndex;
+        $encryptParseItem->endIndex = $indexOfXmlNode + strlen($xmlEndNode);
+
+        return $encryptParseItem;
+    }
+
+    private function parserEncryptJSONSignSource($request, $responseContent)
+    {
+        $apiName = $request->getApiMethodName();
+        $rootNodeName = str_replace(".", "_", $apiName).$this->RESPONSE_SUFFIX;
+
+        $rootIndex = strpos($responseContent, $rootNodeName);
+        $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE);
+
+        if ($rootIndex > 0) {
+            return $this->parserEncryptJSONItem($responseContent, $rootNodeName, $rootIndex);
+        } else {
+            if ($errorIndex > 0) {
+                return $this->parserEncryptJSONItem($responseContent, $this->ERROR_RESPONSE, $errorIndex);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    private function parserEncryptJSONItem($responseContent, $nodeName, $nodeIndex)
+    {
+        $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2;
+        $signIndex = strpos($responseContent, "\"".$this->SIGN_NODE_NAME."\"");
+        // 签名前-逗号
+        $signDataEndIndex = $signIndex - 1;
+
+        if ($signDataEndIndex < 0) {
+            $signDataEndIndex = strlen($responseContent) - 1;
+        }
+
+        $indexLen = $signDataEndIndex - $signDataStartIndex;
+
+        $encContent = substr($responseContent, $signDataStartIndex + 1, $indexLen - 2);
+
+        $encryptParseItem = new EncryptParseItem();
+
+        $encryptParseItem->encryptContent = $encContent;
+        $encryptParseItem->startIndex = $signDataStartIndex;
+        $encryptParseItem->endIndex = $signDataEndIndex;
+
+        return $encryptParseItem;
+    }
+
+    protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt)
+    {
+        $localIp = isset ($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI";
+        $logData = array(
+            date("Y-m-d H:i:s"),
+            $apiName,
+            $this->appId,
+            $localIp,
+            PHP_OS,
+            $this->alipaySdkVersion,
+            $requestUrl,
+            $errorCode,
+            str_replace("\n", "", $responseTxt)
+        );
+        Log::record(sprintf("alibank::error:\t%s", json_encode($logData)), Log::ERR);
+    }
+
+    function parserJSONSignData($request, $responseContent, $responseJSON)
+    {
+        $signData = new SignData();
+        $signData->sign = $this->parserJSONSign($responseJSON);
+        $signData->signSourceData = $this->parserJSONSignSource($request, $responseContent);
+        return $signData;
+    }
+}

+ 563 - 0
data/api/alibank/coupon.php

@@ -0,0 +1,563 @@
+<?php
+/**
+ * 支付宝立减金接口
+ */
+namespace alibank;
+
+define('ALIBANK_PATHEX', BASE_DATA_PATH . '/api/alibank');
+if (!defined('ALIPAY_PATHEX')) define('ALIPAY_PATHEX', BASE_DATA_PATH . '/api/aop');
+
+require_once(ALIPAY_PATHEX.'/AopClient.php');
+require_once(ALIPAY_PATHEX.'/EncryptParseItem.php');
+require_once(ALIPAY_PATHEX.'/SignData.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustActivityconfigQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustChannelvoucherSendRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustActivityorderQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustChannelvoucherconfigQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankActivitybillQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustAccountQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankDailybillCreateRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayDataBillBalanceQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustChannelvoucherconfigQueryRequest.php');
+require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankDailybillQueryRequest.php');
+require_once(ALIBANK_PATHEX.'/encrypt.php');
+require_once(ALIBANK_PATHEX . '/client.php');
+require_once(ALIBANK_PATHEX . '/response.php');
+
+use alibank\client;
+use aop\AlipayUserDtbankcustActivityconfigQueryRequest;
+use aop\AlipayUserDtbankcustChannelvoucherSendRequest;
+use aop\AlipayUserDtbankcustActivityorderQueryRequest;
+use aop\AlipayUserDtbankActivitybillQueryRequest;
+use aop\AlipayUserDtbankcustAccountQueryRequest;
+use aop\AlipayUserDtbankDailybillCreateRequest;
+use aop\AlipayUserDtbankDailybillQueryRequest;
+use aop\AlipayDataBillBalanceQueryRequest;
+use aop\AlipayUserDtbankcustChannelvoucherconfigQueryRequest;
+use Exception;
+class coupon {
+
+    use \alibank\response;
+
+    const ALIPAY_SERVER_URL = "https://openapi.alipay.com";
+    const ALIPAY_GATEWAY = "/gateway.do";
+    const ALIPAY_SIGN_TYPE = "RSA2";
+    const ALIPAY_FORMAT = "json";
+    const ALIPAY_POST_CHARSET = "UTF-8";
+    const ALIPAY_API_VERSION = "1.0";
+
+    private $aop = NULL;
+    private static $_instance = NULL;
+
+    private function __construct(client $aop)
+    {
+        $this->aop = $aop;
+    }
+
+    public static function getInstance(): coupon
+    {
+        if (self::$_instance == NULL){
+            $config = self::load_config();
+
+            $aop = new client ();
+            $aop->gatewayUrl = self::ALIPAY_SERVER_URL.self::ALIPAY_GATEWAY;
+            $aop->appId = $config['app_id'];
+            $aop->rsaPrivateKey = $config['rsa_private_key'];
+            $aop->alipayrsaPublicKey = $config['alipay_rsa_public_key'];
+            $aop->apiVersion = self::ALIPAY_API_VERSION;
+            $aop->signType = self::ALIPAY_SIGN_TYPE;
+            $aop->postCharset = self::ALIPAY_POST_CHARSET;
+            $aop->format = self::ALIPAY_FORMAT;
+            $aop->encryptKey = $config['encrypt_key'];
+            self::$_instance = new coupon($aop);
+        }
+        return self::$_instance;
+    }
+
+    private static function load_config()
+    {
+        return include(ALIBANK_PATHEX . '/config.php');
+    }
+
+    private function check_user(array $params): bool
+    {
+        $user_fields = ['open_id', 'logon_id', 'phone_id'];
+        foreach ($user_fields as $user_id)
+        {
+            if (!empty($params[$user_id])){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 数字分行活动配置查询接口,$activity_type默认传DISCOUNT(立减金)
+     * @param  string  $activity_id
+     * @param  string  $activity_type DISCOUNT(立减金)|VOUCHER(通用渠道红包)|FIRST_BIND_CARD_GIFT(首绑有礼)
+     * @return array
+     */
+    public function query_activity_config(string $activity_id, string $activity_type = 'DISCOUNT'): array
+    {
+        $biz_content = [];
+
+        $biz_content['activity_id'] = $activity_id;
+        $biz_content['activity_type'] = $activity_type;
+
+        if (empty($biz_content['activity_id'] || empty($biz_content['activity_type']))){
+            return $this->failed('参数有误');
+        }
+
+        $request = new AlipayUserDtbankcustActivityconfigQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false){
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 发放红包
+     * @param  string  $open_id  支付宝用户openid
+     * @param  string  $logon_id  支付宝用户ID
+     * @param  string  $phone_id  支付宝账号
+     * @param  string  $activity_id 数字分行活动id
+     * @param  string  $out_biz_no 外部业务号
+     * @return array
+     */
+    public function send_voucher(string $open_id, string $logon_id, string $phone_id, string $activity_id, string $out_biz_no): array
+    {
+        $biz_content = [];
+        if (!empty($open_id)){
+            $biz_content['open_id'] = $open_id;
+        }
+        if (!empty($logon_id)){
+            $biz_content['logon_id'] = $logon_id;
+        }
+        if (!empty($phone_id)){
+            $biz_content['phone_id'] = $phone_id;
+        }
+
+        $biz_content['activity_id'] = $activity_id;
+        $biz_content['out_biz_no'] = $out_biz_no;
+
+        if (!$this->check_user($biz_content)){
+            return $this->failed('用户信息错误');
+        }
+        if (empty($biz_content['activity_id'] || empty($biz_content['out_biz_no']))){
+            return $this->failed('参数有误');
+        }
+
+        $request = new AlipayUserDtbankcustChannelvoucherSendRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false){
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 查询红包流水
+     * @param  string  $activity_id 数字分行活动id
+     * @param  string  $out_biz_no 外部业务号
+     * @param  string  $open_id 支付宝用户open_id
+     * @param  string  $logon_id 登录ID
+     * @param  string  $phone_id 用户手机号
+     * @param  string  $activity_order_id 活动流水唯一id
+     * @return array
+     */
+    public function query_order(string $activity_order_id, string $open_id, string $logon_id, string $phone_id, string $activity_id, string $out_biz_no): array
+    {
+        $biz_content = [];
+
+        if (!empty($activity_order_id)){
+            $biz_content['activity_order_id'] = $activity_order_id;
+        }
+        if (!empty($open_id)){
+            $biz_content['open_id'] = $open_id;
+        }
+        if (!empty($logon_id)){
+            $biz_content['logon_id'] = $logon_id;
+        }
+        if (!empty($phone_id)){
+            $biz_content['phone_id'] = $phone_id;
+        }
+        if (!empty($activity_id)){
+            $biz_content['activity_id'] = $activity_id;
+        }
+        if (!empty($out_biz_no)){
+            $biz_content['out_biz_no'] = $out_biz_no;
+        }
+
+        if (!$this->check_user($biz_content)){
+            return $this->failed('用户信息错误');
+        }
+        if (empty($biz_content['activity_order_id']) && (empty($biz_content['activity_id']) || empty($biz_content['out_biz_no'])))
+        {
+            return $this->failed('参数有误');
+        }
+
+        $request = new AlipayUserDtbankcustActivityorderQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp  = $this->aop->execute($request);
+            if ($resp === false){
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 验证签名
+     * @param array $params
+     * @return bool
+     */
+    public function verify_sign(array $params): bool
+    {
+        if (!$this->aop->rsaCheckV1($params, null, 'RSA2')){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 查询活动账单
+     * @param string $activity_id
+     * @return array
+     */
+    public function query_activity_bill(string $activity_id): array
+    {
+        if (empty($activity_id)){
+            return $this->failed('参数有误');
+        }
+
+        $biz_content = [
+            'activity_id' => $activity_id,
+            'bill_type' => 'ALL'
+        ];
+
+        $request = new AlipayUserDtbankActivitybillQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false) {
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 数字分行红包活动配置查询接口
+     * @param  string  $activity_id
+     * @return array
+     */
+    public function query_channel_voucher_config(string $activity_id): array
+    {
+        if (empty($activity_id)){
+            return $this->failed('参数有误');
+        }
+
+        $biz_content = [
+            'activity_id' => $activity_id
+        ];
+
+        $request = new AlipayUserDtbankcustChannelvoucherconfigQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false) {
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 创建日账单
+     * @param  string  $start_time eg.2020-01-01 00:00:00
+     * @param  string  $end_time eg.2020-01-01 00:00:00
+     * @return array
+     */
+    public function create_daily_bill(string $start_time, string $end_time):array
+    {
+        $biz_content = [
+            'start_time' => $start_time,
+            'end_time' => $end_time,
+            'bill_type' => 'ALL'
+        ];
+
+        $request = new AlipayUserDtbankDailybillCreateRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false) {
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 下载日账单
+     * @param  string  $bill_id
+     * @return array
+     */
+    public function query_daily_bill(string $bill_id):array
+    {
+        $biz_content = [
+            'bill_id' => $bill_id,
+        ];
+
+        $request = new AlipayUserDtbankDailybillQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false) {
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /**
+     * 数字分行用户账号查询接口
+     * $logon_id和$phone_id二选一
+     * @param  string  $logon_id
+     * @param  string  $phone_id
+     * @return array
+     */
+    public function query_account(string $logon_id, string $phone_id): array
+    {
+        $biz_content = [];
+        if (!empty($phone_id)) {
+            $biz_content['phone_id'] = $phone_id;
+        }
+        if (!empty($logon_id)) {
+            $biz_content['logon_id'] = $logon_id;
+        }
+        if (empty($biz_content)) {
+            return $this->failed('参数有误');
+        }
+
+        $request = new AlipayUserDtbankcustAccountQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false) {
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode->account_no_info_list, '');
+    }
+
+    /**
+     * @param  string  $bill_user_id  商户ID
+     * 查询商户余额
+     * @return array
+     */
+    public function query_balance(string $bill_user_id): array
+    {
+        if (empty($bill_user_id)) {
+            return $this->failed('参数有误');
+        }
+
+        $biz_content = [
+            'bill_user_id' => $bill_user_id
+        ];
+
+        $request = new AlipayDataBillBalanceQueryRequest();
+        $request->setNeedEncrypt(true);
+        $request->setBizContent(json_encode($biz_content));
+
+        try
+        {
+            $resp = $this->aop->execute($request);
+            if ($resp === false) {
+                return $this->net_err();
+            }
+        }
+        catch (Exception $e)
+        {
+            return $this->failed($e->getMessage());
+        }
+
+        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
+        if (!isset($resp->$responseNode)){
+            return $this->net_err();
+        }
+
+        if ($resp->$responseNode->code != "10000") {
+            $err_msg = $this->api_error_msg($resp->$responseNode);
+            return $this->failed($err_msg);
+        }
+
+        return $this->success($resp->$responseNode);
+    }
+
+    /*
+     * 回调通知解密
+     */
+    public function notify_parse(array $params):array
+    {
+        $charset = $params['charset'];
+        $biz_content = $params['biz_content'];
+        $data = $this->aop->decryptJSONSignSource($biz_content, $charset);
+        if (empty($data)) {
+            return $this->failed('回调通知解析失败');
+        }
+
+        return $this->success($data, '');
+    }
+}

+ 77 - 0
data/api/alibank/encrypt.php

@@ -0,0 +1,77 @@
+<?php
+namespace alibank;
+
+/**
+ *   加密工具类
+ */
+class encrypt
+{
+    /**
+     * 加密方法
+     * @param string $str
+     * @return string
+     */
+    public static function encrypt($str, $screct_key)
+    {
+        //AES, 128 模式加密数据 CBC
+        $screct_key = base64_decode($screct_key);
+        $str = trim($str);
+        $str = encrypt::addPKCS7Padding($str);
+
+        //设置全0的IV
+
+        $iv = str_repeat("\0", 16);
+        $encrypt_str = openssl_encrypt($str, 'aes-128-cbc', $screct_key, OPENSSL_NO_PADDING, $iv);
+        return base64_encode($encrypt_str);
+    }
+
+    /**
+     * 解密方法
+     * @param string $str
+     * @return string
+     */
+    public static function decrypt($str, $screct_key)
+    {
+        //AES, 128 模式加密数据 CBC
+        $str = base64_decode($str);
+        $screct_key = base64_decode($screct_key);
+
+        //设置全0的IV
+        $iv = str_repeat("\0", 16);
+        $decrypt_str = openssl_decrypt($str, 'aes-128-cbc', $screct_key, OPENSSL_NO_PADDING, $iv);
+        $decrypt_str = encrypt::stripPKSC7Padding($decrypt_str);
+        return $decrypt_str;
+    }
+
+    /**
+     * 填充算法
+     * @param string $source
+     * @return string
+     */
+    public static function addPKCS7Padding($source)
+    {
+        $source = trim($source);
+        $block = 16;
+
+        $pad = $block - (strlen($source) % $block);
+        if ($pad <= $block) {
+            $char = chr($pad);
+            $source .= str_repeat($char, $pad);
+        }
+        return $source;
+    }
+
+    /**
+     * 移去填充算法
+     * @param string $source
+     * @return string
+     */
+    public static function stripPKSC7Padding($source)
+    {
+        $char = substr($source, -1);
+        $num = ord($char);
+        if ($num == 62) return $source;
+        $source = substr($source, 0, -$num);
+        return $source;
+    }
+}

+ 67 - 0
data/api/alibank/response.php

@@ -0,0 +1,67 @@
+<?php
+namespace alibank;
+
+trait response {
+
+    public function success($data): array
+    {
+        return $this->api_response(true, $data, '', false);
+    }
+
+    public function failed($msg): array
+    {
+        return $this->api_response(false, [], $msg, false);
+    }
+
+    public function net_err(): array
+    {
+        return $this->api_response(false, [], '网络错误', true);
+    }
+
+    /*
+     * return [是否执行成功,成功时返回的数据,失败原因]
+     */
+    public function api_response($state, $data, $msg, $net_err): array
+    {
+        if ($state === true)
+        {
+            if (is_object($data)) {
+                $data = json_decode(json_encode($data), true);
+            }
+
+            if (is_array($data))
+            {
+                foreach ($data as &$item)
+                {
+                    if (is_object($item)) {
+                        $item = json_decode(json_encode($item), true);
+                    }
+                }
+            }
+
+            if (empty($data)) {
+                $data = [];
+            }
+
+            return [true, $data, '', false];
+        }
+
+        return [false, [], $msg, $net_err];
+    }
+
+    /*
+     * 获取接口返回错误信息,部分接口文档定义的错误示例字段与实际调试有出入,判断多个字段防止取不到错误提示信息
+     */
+    public function api_error_msg($ali_response): string
+    {
+        if (isset($ali_response->sub_msg)) {
+            return $ali_response->sub_msg;
+        }
+
+        if (isset($ali_response->message)) {
+            return $ali_response->message;
+        }
+
+        return '未知错误';
+    }
+}

+ 120 - 0
data/api/aop/request/AlipayDataBillBalanceQueryRequest.php

@@ -0,0 +1,120 @@
+<?php
+namespace aop;
+
+/**
+ * ALIPAY API: alipay.data.bill.balance.query request
+ *
+ * @author auto create
+ * @since 1.0, 2023-09-11 17:36:45
+ */
+class AlipayDataBillBalanceQueryRequest
+{
+    /**
+     * 支付宝商家账户当前余额查询
+     **/
+    private $bizContent;
+
+    private $apiParas = array();
+    private $terminalType;
+    private $terminalInfo;
+    private $prodCode;
+    private $apiVersion="1.0";
+    private $notifyUrl;
+    private $returnUrl;
+    private $needEncrypt=false;
+
+
+    public function setBizContent($bizContent)
+    {
+        $this->bizContent = $bizContent;
+        $this->apiParas["biz_content"] = $bizContent;
+    }
+
+    public function getBizContent()
+    {
+        return $this->bizContent;
+    }
+
+    public function getApiMethodName()
+    {
+        return "alipay.data.bill.balance.query";
+    }
+
+    public function setNotifyUrl($notifyUrl)
+    {
+        $this->notifyUrl=$notifyUrl;
+    }
+
+    public function getNotifyUrl()
+    {
+        return $this->notifyUrl;
+    }
+
+    public function setReturnUrl($returnUrl)
+    {
+        $this->returnUrl=$returnUrl;
+    }
+
+    public function getReturnUrl()
+    {
+        return $this->returnUrl;
+    }
+
+    public function getApiParas()
+    {
+        return $this->apiParas;
+    }
+
+    public function getTerminalType()
+    {
+        return $this->terminalType;
+    }
+
+    public function setTerminalType($terminalType)
+    {
+        $this->terminalType = $terminalType;
+    }
+
+    public function getTerminalInfo()
+    {
+        return $this->terminalInfo;
+    }
+
+    public function setTerminalInfo($terminalInfo)
+    {
+        $this->terminalInfo = $terminalInfo;
+    }
+
+    public function getProdCode()
+    {
+        return $this->prodCode;
+    }
+
+    public function setProdCode($prodCode)
+    {
+        $this->prodCode = $prodCode;
+    }
+
+    public function setApiVersion($apiVersion)
+    {
+        $this->apiVersion=$apiVersion;
+    }
+
+    public function getApiVersion()
+    {
+        return $this->apiVersion;
+    }
+
+    public function setNeedEncrypt($needEncrypt)
+    {
+
+        $this->needEncrypt=$needEncrypt;
+
+    }
+
+    public function getNeedEncrypt()
+    {
+        return $this->needEncrypt;
+    }
+
+}

+ 120 - 0
data/api/aop/request/AlipayUserDtbankDailybillCreateRequest.php

@@ -0,0 +1,120 @@
+<?php
+namespace aop;
+
+/**
+ * ALIPAY API: alipay.user.dtbank.dailybill.create request
+ *
+ * @author auto create
+ * @since 1.0, 2023-08-21 02:11:43
+ */
+class AlipayUserDtbankDailybillCreateRequest
+{
+    /**
+     * 日账单创建
+     **/
+    private $bizContent;
+
+    private $apiParas = array();
+    private $terminalType;
+    private $terminalInfo;
+    private $prodCode;
+    private $apiVersion="1.0";
+    private $notifyUrl;
+    private $returnUrl;
+    private $needEncrypt=false;
+
+
+    public function setBizContent($bizContent)
+    {
+        $this->bizContent = $bizContent;
+        $this->apiParas["biz_content"] = $bizContent;
+    }
+
+    public function getBizContent()
+    {
+        return $this->bizContent;
+    }
+
+    public function getApiMethodName()
+    {
+        return "alipay.user.dtbank.dailybill.create";
+    }
+
+    public function setNotifyUrl($notifyUrl)
+    {
+        $this->notifyUrl=$notifyUrl;
+    }
+
+    public function getNotifyUrl()
+    {
+        return $this->notifyUrl;
+    }
+
+    public function setReturnUrl($returnUrl)
+    {
+        $this->returnUrl=$returnUrl;
+    }
+
+    public function getReturnUrl()
+    {
+        return $this->returnUrl;
+    }
+
+    public function getApiParas()
+    {
+        return $this->apiParas;
+    }
+
+    public function getTerminalType()
+    {
+        return $this->terminalType;
+    }
+
+    public function setTerminalType($terminalType)
+    {
+        $this->terminalType = $terminalType;
+    }
+
+    public function getTerminalInfo()
+    {
+        return $this->terminalInfo;
+    }
+
+    public function setTerminalInfo($terminalInfo)
+    {
+        $this->terminalInfo = $terminalInfo;
+    }
+
+    public function getProdCode()
+    {
+        return $this->prodCode;
+    }
+
+    public function setProdCode($prodCode)
+    {
+        $this->prodCode = $prodCode;
+    }
+
+    public function setApiVersion($apiVersion)
+    {
+        $this->apiVersion=$apiVersion;
+    }
+
+    public function getApiVersion()
+    {
+        return $this->apiVersion;
+    }
+
+    public function setNeedEncrypt($needEncrypt)
+    {
+
+        $this->needEncrypt=$needEncrypt;
+
+    }
+
+    public function getNeedEncrypt()
+    {
+        return $this->needEncrypt;
+    }
+
+}

+ 120 - 0
data/api/aop/request/AlipayUserDtbankDailybillQueryRequest.php

@@ -0,0 +1,120 @@
+<?php
+namespace aop;
+
+/**
+ * ALIPAY API: alipay.user.dtbank.dailybill.query request
+ *
+ * @author auto create
+ * @since 1.0, 2023-08-21 05:51:44
+ */
+class AlipayUserDtbankDailybillQueryRequest
+{
+    /**
+     * 日账单查询接口
+     **/
+    private $bizContent;
+
+    private $apiParas = array();
+    private $terminalType;
+    private $terminalInfo;
+    private $prodCode;
+    private $apiVersion="1.0";
+    private $notifyUrl;
+    private $returnUrl;
+    private $needEncrypt=false;
+
+
+    public function setBizContent($bizContent)
+    {
+        $this->bizContent = $bizContent;
+        $this->apiParas["biz_content"] = $bizContent;
+    }
+
+    public function getBizContent()
+    {
+        return $this->bizContent;
+    }
+
+    public function getApiMethodName()
+    {
+        return "alipay.user.dtbank.dailybill.query";
+    }
+
+    public function setNotifyUrl($notifyUrl)
+    {
+        $this->notifyUrl=$notifyUrl;
+    }
+
+    public function getNotifyUrl()
+    {
+        return $this->notifyUrl;
+    }
+
+    public function setReturnUrl($returnUrl)
+    {
+        $this->returnUrl=$returnUrl;
+    }
+
+    public function getReturnUrl()
+    {
+        return $this->returnUrl;
+    }
+
+    public function getApiParas()
+    {
+        return $this->apiParas;
+    }
+
+    public function getTerminalType()
+    {
+        return $this->terminalType;
+    }
+
+    public function setTerminalType($terminalType)
+    {
+        $this->terminalType = $terminalType;
+    }
+
+    public function getTerminalInfo()
+    {
+        return $this->terminalInfo;
+    }
+
+    public function setTerminalInfo($terminalInfo)
+    {
+        $this->terminalInfo = $terminalInfo;
+    }
+
+    public function getProdCode()
+    {
+        return $this->prodCode;
+    }
+
+    public function setProdCode($prodCode)
+    {
+        $this->prodCode = $prodCode;
+    }
+
+    public function setApiVersion($apiVersion)
+    {
+        $this->apiVersion=$apiVersion;
+    }
+
+    public function getApiVersion()
+    {
+        return $this->apiVersion;
+    }
+
+    public function setNeedEncrypt($needEncrypt)
+    {
+
+        $this->needEncrypt=$needEncrypt;
+
+    }
+
+    public function getNeedEncrypt()
+    {
+        return $this->needEncrypt;
+    }
+
+}

+ 119 - 0
data/api/aop/request/AlipayUserDtbankcustActivityconfigQueryRequest.php

@@ -0,0 +1,119 @@
+<?php
+namespace aop;
+/**
+ * ALIPAY API: alipay.user.dtbankcust.activityconfig.query request
+ *
+ * @author auto create
+ * @since 1.0, 2023-08-21 05:41:42
+ */
+class AlipayUserDtbankcustActivityconfigQueryRequest
+{
+    /**
+     * 数字分行活动配置查询接口
+     **/
+    private $bizContent;
+
+    private $apiParas = array();
+    private $terminalType;
+    private $terminalInfo;
+    private $prodCode;
+    private $apiVersion="1.0";
+    private $notifyUrl;
+    private $returnUrl;
+    private $needEncrypt=false;
+
+
+    public function setBizContent($bizContent)
+    {
+        $this->bizContent = $bizContent;
+        $this->apiParas["biz_content"] = $bizContent;
+    }
+
+    public function getBizContent()
+    {
+        return $this->bizContent;
+    }
+
+    public function getApiMethodName()
+    {
+        return "alipay.user.dtbankcust.activityconfig.query";
+    }
+
+    public function setNotifyUrl($notifyUrl)
+    {
+        $this->notifyUrl=$notifyUrl;
+    }
+
+    public function getNotifyUrl()
+    {
+        return $this->notifyUrl;
+    }
+
+    public function setReturnUrl($returnUrl)
+    {
+        $this->returnUrl=$returnUrl;
+    }
+
+    public function getReturnUrl()
+    {
+        return $this->returnUrl;
+    }
+
+    public function getApiParas()
+    {
+        return $this->apiParas;
+    }
+
+    public function getTerminalType()
+    {
+        return $this->terminalType;
+    }
+
+    public function setTerminalType($terminalType)
+    {
+        $this->terminalType = $terminalType;
+    }
+
+    public function getTerminalInfo()
+    {
+        return $this->terminalInfo;
+    }
+
+    public function setTerminalInfo($terminalInfo)
+    {
+        $this->terminalInfo = $terminalInfo;
+    }
+
+    public function getProdCode()
+    {
+        return $this->prodCode;
+    }
+
+    public function setProdCode($prodCode)
+    {
+        $this->prodCode = $prodCode;
+    }
+
+    public function setApiVersion($apiVersion)
+    {
+        $this->apiVersion=$apiVersion;
+    }
+
+    public function getApiVersion()
+    {
+        return $this->apiVersion;
+    }
+
+    public function setNeedEncrypt($needEncrypt)
+    {
+
+        $this->needEncrypt=$needEncrypt;
+
+    }
+
+    public function getNeedEncrypt()
+    {
+        return $this->needEncrypt;
+    }
+
+}

+ 0 - 254
helper/pay/AlipayCoupon.php

@@ -1,254 +0,0 @@
-<?php
-/**
- * 支付宝立减金接口封装
- */
-namespace pay;
-
-if (!defined('ALIPAY_PATHEX')) define('ALIPAY_PATHEX', BASE_DATA_PATH . '/api/aop');
-
-require_once(ALIPAY_PATHEX . '/AopClient.php');
-require_once(ALIPAY_PATHEX . '/AopEncrypt.php');
-require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustChannelvoucherSendRequest.php');
-require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustActivityorderQueryRequest.php');
-require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustChannelvoucherconfigQueryRequest.php');
-require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankActivitybillQueryRequest.php');
-require_once(ALIPAY_PATHEX . '/request/AlipayUserDtbankcustAccountQueryRequest.php');
-
-use aop\AopClient;
-use aop\AlipayUserDtbankcustChannelvoucherSendRequest;
-use aop\AlipayUserDtbankcustActivityorderQueryRequest;
-use aop\AlipayUserDtbankActivitybillQueryRequest;
-use aop\AlipayUserDtbankcustAccountQueryRequest;
-use Exception;
-
-class AlipayCoupon {
-    const ALIPAY_SERVER_URL = "https://openapi.alipay.com";
-    const ALIPAY_GATEWAY = "/gateway.do";
-    const ALIPAY_SIGN_TYPE = "RSA2";
-    const ALIPAY_FORMAT = "json";
-    const ALIPAY_POST_CHARSET = "UTF-8";
-    const ALIPAY_API_VERSION = "1.0";
-
-    private $aop_client = NULL;
-    private static $_instance = NULL;
-
-    private function __construct(AopClient $aop){
-        $this->aop_client = $aop;
-    }
-
-    public static function getInstance(string $app_id, string $rsa_private_key, string $rsa_public_key): AlipayCoupon
-    {
-        if (self::$_instance == NULL){
-            $aop = new AopClient ();
-            $aop->gatewayUrl = self::ALIPAY_SERVER_URL.self::ALIPAY_GATEWAY;
-            $aop->appId = $app_id;
-            $aop->rsaPrivateKey = $rsa_private_key;
-            $aop->alipayrsaPublicKey = $rsa_public_key;
-            $aop->apiVersion = self::ALIPAY_API_VERSION;
-            $aop->signType = self::ALIPAY_SIGN_TYPE;
-            $aop->postCharset = self::ALIPAY_POST_CHARSET;
-            $aop->format = self::ALIPAY_FORMAT;
-            self::$_instance = new AlipayCoupon($aop);
-        }
-        return self::$_instance;
-    }
-
-    private function check_voucher_key(array $params): bool
-    {
-        if (empty($biz_content['open_id']) && empty($biz_content['logon_id']) && empty($biz_content['phone_id'])) {
-            return false;
-        }
-        if (empty($biz_content['activity_id']) || empty($biz_content['out_biz_no'])) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 发放立减金
-     * @param  string  $activity_id
-     * @param  string  $out_biz_no
-     * @param  string  $open_id
-     * @param  string  $logon_id
-     * @param  string  $phone_id
-     * @return array
-     */
-    public function send_voucher(string $activity_id, string $out_biz_no, string $open_id = '', string $logon_id = '', string $phone_id = ''): array
-    {
-        $biz_content = [];
-        if (!empty($open_id)){
-            $biz_content['open_id'] = $open_id;
-        }
-        if (!empty($logon_id)){
-            $biz_content['logon_id'] = $logon_id;
-        }
-        if (!empty($phone_id)){
-            $biz_content['phone_id'] = $phone_id;
-        }
-
-        $biz_content['activity_id'] = $activity_id;
-        $biz_content['out_biz_no'] = $out_biz_no;
-
-        if (!$this->check_voucher_key($biz_content)){
-            return [false, '参数错误'];
-        }
-
-        $request = new AlipayUserDtbankcustChannelvoucherSendRequest();
-        $request->setBizContent(json_encode($biz_content));
-
-        try
-        {
-            $resp = $this->aop_client->execute($request);
-            if ($resp === false){
-                return [false, '网络错误'];
-            }
-        }
-        catch (Exception $e)
-        {
-            return [false, $e->getMessage()];
-        }
-
-        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
-        return [$resp->$responseNode, ''];
-    }
-
-    /**
-     * 查询红包流水
-     * @param  string  $activity_id
-     * @param  string  $out_biz_no
-     * @param  string  $open_id
-     * @param  string  $logon_id
-     * @param  string  $phone_id
-     * @return array
-     */
-    public function query_order(string $activity_id, string $out_biz_no, string $open_id = '', string $logon_id = '', string $phone_id = ''): array
-    {
-        if (!empty($open_id)){
-            $biz_content['open_id'] = $open_id;
-        }
-        if (!empty($logon_id)){
-            $biz_content['logon_id'] = $logon_id;
-        }
-        if (!empty($phone_id)){
-            $biz_content['phone_id'] = $phone_id;
-        }
-
-        $biz_content['activity_id'] = $activity_id;
-        $biz_content['out_biz_no'] = $out_biz_no;
-
-        if (!$this->check_voucher_key($biz_content)){
-            return [false, '参数错误'];
-        }
-
-        $request = new AlipayUserDtbankcustActivityorderQueryRequest();
-        $request->setBizContent(json_encode($biz_content));
-
-        try
-        {
-            $resp  = $this->aop_client->execute($request);
-            if ($resp === false){
-                return [false, '网络错误'];
-            }
-        }
-        catch (Exception $e)
-        {
-            return [false, $e->getMessage()];
-        }
-
-        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
-        return [$resp->$responseNode, ''];
-    }
-
-    /**
-     * 验证签名
-     * @param array $params
-     * @return bool
-     */
-    public function verify_sign(array $params): bool
-    {
-        if (!$this->aop_client->rsaCheckV1($params, null, 'RSA2')){
-            return false;
-        }
-        return true;
-    }
-
-    public function on_notify(array $params): array
-    {
-        return [];
-    }
-
-    /**
-     * 查询活动账单
-     * @param string $activity_id
-     * @return array
-     */
-    public function query_activity_bill(string $activity_id): array
-    {
-        if (empty($activity_id)){
-            return [false, '参数错误'];
-        }
-
-        $biz_content = [
-            'activity_id' => $activity_id,
-            'bill_type' => 'ALL'
-        ];
-        $request = new AlipayUserDtbankActivitybillQueryRequest();
-        $request->setBizContent(json_encode($biz_content));
-
-        try
-        {
-            $resp = $this->aop_client->execute($request);
-            if ($resp === false) {
-                return [false, '网络错误'];
-            }
-        }
-        catch (Exception $e)
-        {
-            return [false, $e->getMessage()];
-        }
-
-        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
-        return [$resp->$responseNode, ''];
-    }
-
-    /**
-     * 数字分行用户账号查询接口
-     * $logon_id和$phone_id二选一
-     * @param $logon_id
-     * @param $phone_id
-     * @return array
-     */
-    public function query_account($logon_id,$phone_id): array
-    {
-        $biz_content = [];
-        if (!empty($phone_id)) {
-            $biz_content['phone_id'] = $phone_id;
-        }
-        if (!empty($logon_id)) {
-            $biz_content['logon_id'] = $logon_id;
-        }
-        if (empty($biz_content)) {
-            return [false, '参数错误'];
-        }
-
-        $request = new AlipayUserDtbankcustAccountQueryRequest();
-        $request->setBizContent(json_encode($biz_content));
-
-        try
-        {
-            $resp = $this->aop_client->execute($request);
-            if ($resp === false) {
-                return [false, '网络错误'];
-            }
-        }
-        catch (Exception $e)
-        {
-            return [false, $e->getMessage()];
-        }
-
-        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
-        return [$resp->$responseNode, ''];
-    }
-}
-
-?>

+ 0 - 4
helper/refill/api/xyz/alipay_coupon/API.MD

@@ -1,4 +0,0 @@
-## 支付宝立减金
-
-### 文档
-https://www.yuque.com/xv2p76/manual/mg9649

+ 0 - 52
helper/refill/api/xyz/alipay_coupon/RefillCallBack.php

@@ -1,52 +0,0 @@
-<?php
-namespace refill\alipay_coupon;
-
-require_once(BASE_HELPER_RAPI_PATH . '/alipay_coupon/config.php');
-
-use refill;
-use Log;
-class RefillCallBack implements refill\IRefillCallBack
-{
-    public function verify($params): bool
-    {
-        $aop_client = config::aop_client();
-        if (!$aop_client->rsaCheckV1($params, null, 'RSA2')){
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * @param $params
-     * @return array [$order_id, $success, $can_try, $need_handle, $official_sn]
-     */
-    public function notify($params): array
-    {
-        $result = json_decode($params['biz_content'], true);
-        if (!$result){
-            return [false, false, false, false, ''];
-        }
-
-        $status = $result['biz_type']; //券发放(V_BATCH_PUBLISH)、券过期(V_EXPIRE),券删除(V_DELETE)、券核销(V_USE)
-
-        $org_order_id = $result['order_id'];
-        $order_info = Model('refill_order')->getOrderInfo(['ch_trade_no' => $org_order_id]);
-        if (empty($order_info)) {
-            return [false, false, false, false, ''];
-        }
-
-        $order_id = $order_info['order_id'];
-        if ($status == 'V_USE') { //使用成功,success:是,can_try:否,need_handle:处理业务数据(成功)
-            $official_sn = $result['trade_no'];
-            $data['official_sn'] = $official_sn;
-            Model('refill_order')->edit($order_id, $data);
-            return [$order_id, true, false, true, $official_sn];
-        } elseif ($status == 'V_BATCH_PUBLISH') { //券发放阶段,success:是,can_try:否,need_handle:不处理业务数据
-            return [$order_id, true, false, false, ''];
-        } elseif (in_array($status, ['V_EXPIRE', 'V_DELETE'])) { //券过期/券删除,success:否,can_try:否(券作废后不重新发券),need_handle:处理业务数据(失败)
-            return [$order_id, false, false, true, ''];
-        } else { //未知错误,不做业务处理
-            return [$order_id, false, false, false, ''];
-        }
-    }
-}

+ 0 - 137
helper/refill/api/xyz/alipay_coupon/RefillPhone.php

@@ -1,137 +0,0 @@
-<?php
-namespace refill\alipay_coupon;
-
-require_once(BASE_HELPER_PATH . '/pay/AlipayCoupon.php');
-require_once(BASE_HELPER_RAPI_PATH . '/alipay_coupon/config.php');
-
-use refill;
-use pay\AlipayCoupon;
-class RefillPhone extends refill\IRefillThird
-{
-    public function __construct($cfgs)
-    {
-        parent::__construct($cfgs);
-    }
-
-    private function getProductCode($sys_pcode)
-    {
-        $thrid_refill = Model('thrid_refill');
-        $product = $thrid_refill->getProduct(['system_code' => $sys_pcode,'opened' => 1]);
-        if (empty($product)) {
-            return false;
-        } else {
-            return $product['channel_code'];
-        }
-    }
-
-    /*
-     * $params 参数说明:logon_id,phone_id不能同时为空,优先级依次降低
-     * open_id 映射user_id
-     * logon_id 支付宝用户ID
-     * phone_id 手机号
-     * activity_id 数字分行活动id
-     * out_biz_no 外部业务号
-     * @return array
-     */
-    public function add($card_no, $card_type, $amount, $params, &$net_errno = 0): array
-    {
-        $order_sn = $params['order_sn'];
-        $channel_code = $this->getProductCode($params['product_code']);
-        if ($channel_code === false) {
-            return [false, '产品有误', false];
-        }
-
-        $ac_client = AlipayCoupon::getInstance(config::ALIPAY_APPID, config::ALIPAY_RSAPRIVATEKEY, config::ALIPAY_ALIPAYRSAPUBLICKEY);
-        [$resp, $err] = $ac_client->send_voucher($channel_code, $order_sn, $params['open_id'] ?? '', $params['logon_id'] ?? '', $params['phone_id'] ?? '');
-        if ($resp === false){
-            return [false, $err, true];
-        }
-
-        $code = intval($resp->code);
-        $sub_code = $resp->sub_code ?? ''; //该字段在成功时可能不存在
-        $err_code = $code.'-'.$sub_code;
-
-        if ($code === 10000)
-        {
-            if ($resp->send_status == 'SUCCESS'){
-                return [true, $resp->activity_order_id, false];
-            } elseif($resp->send_status == 'INTERNAL_RPC_EXCEPTION'){
-                $err = 998;
-                $net_errno = "HTTP-{$err}";
-                return [false, $resp->send_status, true];
-            } else {
-                return [false, $resp->send_status, false];
-            }
-        }
-        elseif (in_array($code, config::ERR_NOS))
-        {
-            return [false, $err_code, false];
-        }
-        else
-        {
-            $err = 998;
-            $net_errno = "HTTP-{$err}";
-            return [false, $err_code, true];
-        }
-    }
-
-    public function query($refill_info): array
-    {
-        $mch_order = $refill_info['mch_order'];
-        $mch_id = $refill_info['mchid'];
-
-        $mod_detail = Model('refill_detail');
-        $refill_detail = $mod_detail->getDetailInfo(['mchid' => $mch_id, 'mch_order' => $mch_order]);
-
-        if (empty($refill_detail)){
-            return [false, '系统错误', ''];
-        }
-
-        $params = json_decode($refill_detail['params'], true);
-        if (empty($params)){
-            return [false, '系统错误', ''];
-        }
-
-        $channel_code = $this->getProductCode($params['product_code']);
-        if ($channel_code === false) {
-            return [false, '产品有误', ''];
-        }
-
-        $ac_client = AlipayCoupon::getInstance(config::ALIPAY_APPID, config::ALIPAY_RSAPRIVATEKEY, config::ALIPAY_ALIPAYRSAPUBLICKEY);
-        [$resp, $err] = $ac_client->query_order($channel_code, $params['out_biz_no'], $params['open_id'] ?? '', $params['logon_id'] ?? '', $params['phone_id'] ?? '');
-        if ($resp === false){
-            return [false, $err, ''];
-        }
-
-        $code = intval($resp->code);
-        $sub_code = $resp->sub_code ?? ''; //该字段在成功时可能不存在
-        $err_code = $code.'-'.$sub_code;
-
-        if ($code === 10000)
-        {
-            $official_sn = $resp->activity_order_id;
-
-            $status = $resp->status;
-            if ($status == 'SUCCESS') {
-                $order_state = ORDER_STATE_SUCCESS;
-            } elseif ($status == 'INIT' || $status == 'PENDING') {
-                $order_state = ORDER_STATE_SEND;
-            } elseif ($status == 'FAILED') {
-                $order_state = ORDER_STATE_CANCEL;
-            } else {
-                return [false, $status, ''];
-            }
-            return [true, $order_state, $official_sn];
-        }
-        else
-        {
-            return [false, $err_code, ''];
-        }
-    }
-
-    public function balance(): array
-    {
-        return [true, 0];
-    }
-
-}

+ 0 - 18
helper/refill/api/xyz/alipay_coupon/config.php

@@ -1,18 +0,0 @@
-<?php
-namespace refill\alipay_coupon;
-
-use aop\AopClient;
-use refill\functional;
-
-class config
-{
-    const NOTIFY_URL = BASE_SITE_URL . "/mobile/callback/refill_alipay_coupon.php";
-
-    const ALIPAY_APPID = "";
-    const ALIPAY_RSAPRIVATEKEY = "";
-    const ALIPAY_ALIPAYRSAPUBLICKEY = "";
-
-    const ERR_NOS = [
-        20001, 40001, 40002, 40003, 40004, 40005, 40006
-    ];
-}

+ 0 - 5
mobile/callback/refill_alipay_coupon.php

@@ -1,5 +0,0 @@
-<?php
-
-refill\util::push_notify('alipay_coupon',$_POST);
-
-echo ('success');

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 32 - 6
test/TestRefill.php