From f10bdebe0240d9ae4b9df4e9e42d2e8b05f4e432 Mon Sep 17 00:00:00 2001 From: DengBiao <2319963317@qq.com> Date: Fri, 18 Aug 2023 23:04:22 +0800 Subject: [PATCH] update --- src/applet/app/config/loader.php | 2 + .../controllers/Alipay/BPassController.php | 3 +- .../Alipay/FaceScanPayController.php | 18 + .../app/controllers/CallBackController.php | 268 +--- src/common/Service/AliBPass/AliEcoService.php | 85 +- .../Service/AliBPass/AliEcoServiceBack.php | 112 ++ .../Service/AliBPass/demo/AliEcoService.php | 167 +++ .../Service/AliBPass/demo/AopEncrypt.php | 136 +- .../{EcoapiClient.php => EcoApiClient.php} | 2 +- .../AliBPass/demo/EncryptParseItem.php | 18 +- .../AliBPass/demo/EncryptResponseData.php | 14 +- src/common/Service/AliBPass/demo/SignData.php | 14 +- .../Service/AliBPass/demo/test/Demo.php | 4 +- src/common/Service/Pay/AlipayK12Service.php | 28 + .../aop/AopClient.php | 1 - .../aop/AopEncrypt256.php | 4 +- .../aop/EcoAopClient.php | 1319 +++++++++++++++++ ...ipayPlanetEcocampusApiRosterSignUpInfo.php | 230 +-- 18 files changed, 1907 insertions(+), 518 deletions(-) create mode 100644 src/common/Service/AliBPass/AliEcoServiceBack.php create mode 100644 src/common/Service/AliBPass/demo/AliEcoService.php rename src/common/Service/AliBPass/demo/{EcoapiClient.php => EcoApiClient.php} (99%) create mode 100644 src/vendor/alipay-sdk-php-all-master/aop/EcoAopClient.php diff --git a/src/applet/app/config/loader.php b/src/applet/app/config/loader.php index 7a0bcf1..0fb8f01 100644 --- a/src/applet/app/config/loader.php +++ b/src/applet/app/config/loader.php @@ -7,10 +7,12 @@ $loader->registerFiles([ DIR_VENDOR . 'alipay/AopClient.php', DIR_VENDOR . 'alipay/AopCertClient.php', DIR_VENDOR . 'alipay-sdk-php-all-master/aop/AopClient.php', + DIR_VENDOR . 'alipay-sdk-php-all-master/aop/EcoAopClient.php', DIR_VENDOR . 'alipay-sdk-php-all-master/aop/request/AlipaySystemOauthTokenRequest.php', // DIR_VENDOR . 'alipay-sdk-php-all-master/aop/AopCertClient.php', // DIR_VENDOR . 'alipay-sdk-php-all-master/aop/AopEncrypt.php', + DIR_VENDOR . 'alipay-sdk-php-all-master/aop/request/AlipayCommerceEducateFacefeatureGroupkeyQueryRequest.php', DIR_VENDOR . 'alipay-sdk-php-all-master/aop/request/AlipayTradeRefundRequest.php', DIR_VENDOR . 'alipay-sdk-php-all-master/aop/request/AlipayTradeCreateRequest.php', DIR_VENDOR . 'alipay-sdk-php-all-master/aop/request/AlipayTradeQueryRequest.php', diff --git a/src/applet/app/controllers/Alipay/BPassController.php b/src/applet/app/controllers/Alipay/BPassController.php index 0a376be..2d8863f 100644 --- a/src/applet/app/controllers/Alipay/BPassController.php +++ b/src/applet/app/controllers/Alipay/BPassController.php @@ -4,7 +4,7 @@ namespace SRVX\Api\Controllers\Alipay; use SRVX\Api\Controllers\ControllerBase; use SRVX\Msg; -use SRVX\Service\AliBPass\AliEcoService; +use SRVX\Service\AliBPass\demo\AliEcoService; class BPassController extends ControllerBase @@ -19,6 +19,7 @@ class BPassController extends ControllerBase { if ($this->request->isPost()) { $args = $this->request->getJsonRawBody(true); + $result = (new AliEcoService())->alipayPlanetEcocampusApiRosterSignUpInfo( $args["face_uid"],$args["parent_uid"], $args["parent_logon_id"], $args["roster_name"], diff --git a/src/applet/app/controllers/Alipay/FaceScanPayController.php b/src/applet/app/controllers/Alipay/FaceScanPayController.php index 9ca4af0..cced366 100644 --- a/src/applet/app/controllers/Alipay/FaceScanPayController.php +++ b/src/applet/app/controllers/Alipay/FaceScanPayController.php @@ -35,4 +35,22 @@ class FaceScanPayController extends ControllerBase } } + public function EducateFaceFeatureGroupKeyQueryAction() + { + if ($this->request->isPost()) { + $args = $this->request->getJsonRawBody(true); + $result = (new AlipayK12Service([ + "ali_app_id" => "2021004103604157", + "ali_private_key" => "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCSGJ9ob4kmGy6y4YeynjKJc/LSg02EXjLErPZSfVrAOy69FTRfBDbazlxpfl6YCAxDdT5ZcspB5kS2XYOY4dmqqPmF4VywmcjmZM8IxZFl1p7YC8BOlP6JrzDPwVl3hn4z3Em1byj8ANLY/AxAaW9W43FSIX+cSfdJThTlxGcbHZFM3kqu++hgFc/E+ar1nB0garqh03ESjatO4b6tuHM57ou7M+fXsoIf3gaL1IDZpeAoRh5sLCBLIbLz55tF0DcOaFsK7NUImnabJDRtrM1IN0lDZkQYAzL+JFsAq+ncRJm60Vd1jq/pXML/cFVHQQgdnjUd2u2NJTSMiCKCftmdAgMBAAECggEARzt+LduEEXJbeJiCI1MC7QX9tSqUFyAevMpgZ6P7JZM1nLfECzfwzwqjAES/Nn1mDVYTCmXvu+XcRtadnWMxUAaHcwGIwgqZa8xnLa220OKuHETOhQIcgWFL+WAakS6gRgT4Y2BJqWV1aJqsFpPR15mZ3SO8JqXhznolsknqw8sO+DBJu+QXn1HdntSGWrLU4GblPlYAs64y/MzPMUWfA4ShDRn9MZK6ypnh2GB5ezgnFxx1jRGOy96IqikI8f+M/CVdgzErLIl+qTd/IbfL8B6Gccb4ZwimL/x1H1bqYCA6xINMZLo5eDHCvBTU4AW7sItw1Q7MQ8l3wBl7hW62gQKBgQDZT1SEaeBtOJxt3vrK7o/kCWNh/4h9oENFhDIuTvLQk9tirKw0BSiZedjbEHqnqM+bgeuvxazCp9uqoYXgC/dtIooy1P8aso+ZrroC/0vZV7TQBGBjbSSkKPn7ShZM2hfYQFpmLznwpel7KJbP6AJ8atv99wjB6uvqNf6fMU7IbQKBgQCsG3mj0amsYbS5ZQZpl2v65QnlkAxv0dxcstx15kW0hXRugLOu7EGcJNZMhO4gbn8dzMOaJANZPG1VLcFpe/QyP/AW7vDt9vTWdeQkQCD5xcXEDihLLCq0pFaSkmuOHWCI+aepSHUILlJ1P/K/5biD7MTdPg6tyLqyM+rjUd/38QKBgQCNu2fsVQHDOsEMB/qakK3YlSb0q61iAjzeAjKYcXV9BHJ6ERTfeN3Z+9asSjs1TqzZSAtoQQ1EiCaFS4P9dNCTpYttS+52gy+VlJhNjCT0RHfxlGkpb+4OA4vHkbKpvTUAHjjXnMW1ZwC5CugSAchdTXTeV1im4Yms4DqJqacwoQKBgQCocPd7An8qTDIBZMOC4oT29+TYvUO+yMkAHLmx1h4QkLCkWegB4g5QkKkAGPWp3hshAj/KA0cXthFXVUG/SGZ2K6eB+nbon1N+9cDETdM4QXzN5gE/mUlupIxqRU1ouI27YYPbJSQNTrC7OkwNzfnpe/gshEj/gr5eHHvd4UrvMQKBgD2Toow7sfpV0R9rhO8aJ9njlbH15LqUK/AotK3E7zr73Uv5j/BIKS4dVC7T56L2khEUbM/y8+Rig6CdyFf3A4i4GKfbp56Sap/Haa9OP6jfep6VW7Aa1AJxPvIPgPZ2U+EuRxrwrP1EBcL5z6Cern9c9Zzs8BPUacU+Q5e8c87W", + "ali_public_key" => "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzEC7+3O/Ej/gkXug6EgcCM3LjWzz11RR6ESo0KshGg3ODgM8DfdKDHD5b1T6VbcRGFobXQBqVtW008ocUnSOZzE67a73l6mKT3FbmhRsbrgwcUuOHEJUZaLFxPibJgFl7fkOjBcIiz+Wc+9VDTt8O4YxIZhAL6L6ppXcrVrCkOaiIiuHGyp7FjQ+5s3Lk3NLSO3TfXw1WEX2F+IHnw32ZN/FlC8rF8HVlgM0w/PZJ9RuadoLqn5H6z/iqrurbtxscnx0Qbdt8CBzREabJnWxHjxO936AXu9njIPvsXkTfaJJIXxRGGb0b8peSiCljwi8UEODe8mjl2c/LzLel6RuLQIDAQAB" + ]))->alipayCommerceEducateFaceFeatureGroupKeyQuery($args["school_std_code"] ?? ""); + if (!$result["status"]) { + $this->api(Msg::NewError($result["data"]["code"] ?? 500, $result["msg"])); + } + $this->api($result["data"]); + } else { + $this->api(Msg::NewError(500, '提交方式错误!')); + } + } + } diff --git a/src/applet/app/controllers/CallBackController.php b/src/applet/app/controllers/CallBackController.php index b39847b..200199a 100644 --- a/src/applet/app/controllers/CallBackController.php +++ b/src/applet/app/controllers/CallBackController.php @@ -24,268 +24,26 @@ class CallBackController extends \Phalcon\Mvc\Controller $args = $this->request->get(); } - /** - * Todo::支付宝 - 授权回调 - */ - public function alipayAuthorizeCallBackAction() - { - $args = $this->request->get(); - $this->logger($args, 'alipay_authorize_callBack_action', true); - if (empty($args['app_id']) || empty($args['app_auth_code']) || empty($args["state"])) { - dd(['msg' => '缺少参数', 'success' => -1]); - } - $result = (new AlipayService())->alipayOpenAuthTokenAppRequest($args['app_auth_code']); - if ($result["status"] != true) { - dd((['msg' => '授权失败', 'success' => -2, "result" => $result])); - } - $app_id = explode("=", base64_decode($args["state"]))[1]; - $merchant_sn = explode("=", base64_decode($args["state"]))[0]; - $uid = explode("_", $merchant_sn)[0]; - $model = MerchantAlipayAuthorize::findFirst("uid = '{$uid}' AND app_id = '{$app_id}' AND merchant_sn = '{$merchant_sn}'"); - $model = empty($model) ? new MerchantAlipayAuthorize() : $model; - $model->uid = $uid; - $model->app_id = $app_id; - $model->merchant_sn = $merchant_sn; - $model->app_auth_token = $result["data"]["tokens"][0]["app_auth_token"]; - $model->app_refresh_token = $result["data"]["tokens"][0]["app_refresh_token"]; - $model->ali_app_id = $args['app_id']; - $model->ali_auth_app_id = $result['data']["tokens"][0]["auth_app_id"]; - $model->ali_user_id = $result["data"]["tokens"][0]["user_id"]; - $model->created_at = date("Y-m-d H:i:s"); - $model->updated_at = date("Y-m-d H:i:s"); - $model->state = ICommon::MERCHANT_STATE_USE; - $model->save(); - dd((['msg' => '授权成功!', 'success' => 0])); - } /** - * 本系统自身支付回调 - 同步 + * 支付宝 - 公共网关回调 */ - public function alipayOwnSyncReturnAction() + public function alipayCommonCallBackAction() { - dump($_GET); $args = $this->request->get(); - logger(json_encode([ - "msg" => "同步回调", - "data" => $args, - ], 320), 'alipay_sync_return', true); - dd($args); - } - - /** - * 本系统自身支付回调 - 异步 - */ - public function alipayOwnSyncNotifyAction() - { + $this->logger($args, 'alipayCommonCallBack', true); if ($this->request->isPost()) { - try { - $verify_result = (new EasyAlipayService())->verifyNotify($_POST); - logger(json_encode([ - "msg" => "异步回调", - "data" => $_POST, - "res" => $verify_result - ], 320), 'alipay_sync_notify', true); - if ($verify_result) {//验证成功 - $out_trade_no = $_POST['out_trade_no']; - //支付宝交易号 - $trade_no = $_POST['trade_no']; - //交易状态 - $trade_status = $_POST['trade_status']; - - //判断该笔订单是否在 - $model = OwnOrder::findFirst("out_trade_no = '{$out_trade_no}'"); - if (!$model) { - //未查到訂單 - logger(json_encode([ - "msg" => "异步回调失败-訂單未查到", - "data" => $_POST, - ], 320), 'alipay_sync_notify_not_find', true); - //验证失败 - echo "fail"; - die(); - } - $model->return_data = json_encode($_POST); - $model->trade_no = $trade_no; - $model->updated_at = date("Y-m-d H:i:s"); - - if ($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') { - //商户网站中已经做过处理 - if ($model->status == IPay::PAY_STATE_FOR_ALREADY) { - logger(json_encode([ - "msg" => "异步回调成功", - "data" => $_POST, - ], 320), 'alipay_sync_notify_already', true); - echo "success"; - die(); - } - $model->status = IPay::PAY_STATE_FOR_ALREADY; - if ($model->save() == false) { - logger(json_encode([ - "msg" => "异步回调-支付成功-更新訂單失敗", - "data" => $_POST, - ], 320), 'alipay_sync_notify_success_update_fail', true); - echo "fail"; - die(); - } - logger(json_encode([ - "msg" => "异步回调支付成功", - "data" => $_POST, - ], 320), 'alipay_sync_notify_success', true); - } else { - $model->status = IPay::PAY_STATE_FOR_FAIL; - if ($model->save() == false) { - logger(json_encode([ - "msg" => "异步回调-支付失敗-更新訂單失敗", - "data" => $_POST, - ], 320), 'alipay_sync_notify_fail_update_fail', true); - echo "fail"; - die(); - } - logger(json_encode([ - "msg" => "异步回调支付失敗", - "data" => $_POST, - ], 320), 'alipay_sync_notify_fail', true); - } - echo "success"; - die(); - } else { - logger(json_encode([ - "msg" => "异步回调驗證失败", - "data" => $_POST, - ], 320), 'alipay_sync_notify_verify_fail', true); - //验证失败 - echo "fail"; - die(); - } - } catch (\Exception $e) { - logger(json_encode([ - "msg" => "异步回调處理异常", - "data" => $params ?? [], - "exception" => $e->getMessage() - ], 320), 'alipay_sync_notify_exception', true); - //回調異常 - echo "fail"; - die(); - } + $args = $this->request->getJsonRawBody(true); + $this->logger($args, 'alipayCommonCallBack_post', true); } - } - - /** - * 支付宝 - 公共网关回调 - */ - public function alipayCommonCallBackAction() - { -// if ($this->request->isPost()) { -// try { -// $verify_result = (new EasyAlipayService())->verifyNotify($_POST); -// logger(json_encode([ -// "msg" => "异步回调", -// "data" => $_POST, -// "res" => $verify_result -// ], 320), 'common_alipay_sync_notify', true); -// if ($verify_result) {//验证成功 -// $self_order_sn = $_POST['out_trade_no']; -// //支付宝交易号 -// $trade_no = $_POST['trade_no']; -// //交易状态 -// $trade_status = $_POST['trade_status']; -// //判断该笔订单是否在 -// $model = UserMerchantOrder::findFirst("self_trade_no = '{$self_order_sn}'"); -// if (!$model) { -// //未查到訂單 -// logger(json_encode([ -// "msg" => "异步回调失败-訂單未查到", -// "data" => $_POST, -// ], 320), 'common_alipay_sync_notify_not_find', true); -// //验证失败 -// echo "fail"; -// die(); -// } -// $model->return_data = json_encode($_POST); -// $model->trade_no = $trade_no; -// $model->updated_at = date("Y-m-d H:i:s"); -// -// #TODO::回調第三方平台的 notify_url -// $passback_params = json_decode(urldecode($_POST["passback_params"]), true); -// $notify_url = $passback_params["notify_url"]; -// $out_trade_no = $passback_params["out_trade_no"]; -// $ext_info = $passback_params["ext_info"] ?? []; -// $isOk = (new GetPlatformCertificateService())->commonCurlNotifyUrl($notify_url, ["out_trade_no" => $out_trade_no, -// "trade_no" => $trade_no, -// "pay_trade_no" => $self_order_sn, -// "trade_status" => $trade_status, -// "ext_info" => $ext_info -// ]); -// if ($isOk) { -// if ($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') { -// //商户网站中已经做过处理 -// if ($model->status == IPay::PAY_STATE_FOR_ALREADY) { -// logger(json_encode([ -// "msg" => "异步回调成功", -// "data" => $_POST, -// ], 320), 'alipay_sync_notify_already', true); -// echo "success"; -// die(); -// } -// $model->status = IPay::PAY_STATE_FOR_ALREADY; -// if ($model->save() == false) { -// logger(json_encode([ -// "msg" => "异步回调-支付成功-更新訂單失敗", -// "data" => $_POST, -// ], 320), 'alipay_sync_notify_success_update_fail', true); -// echo "fail"; -// die(); -// } -// logger(json_encode([ -// "msg" => "异步回调支付成功", -// "data" => $_POST, -// ], 320), 'alipay_sync_notify_success', true); -// } else { -// $model->status = IPay::PAY_STATE_FOR_FAIL; -// if ($model->save() == false) { -// logger(json_encode([ -// "msg" => "异步回调-支付失敗-更新訂單失敗", -// "data" => $_POST, -// ], 320), 'alipay_sync_notify_fail_update_fail', true); -// echo "fail"; -// die(); -// } -// logger(json_encode([ -// "msg" => "异步回调支付失敗", -// "data" => $_POST, -// ], 320), 'alipay_sync_notify_fail', true); -// } -// echo "success"; -// die(); -// } else { -// logger(json_encode([ -// "msg" => "异步回调 - 回調第三方平台失敗", -// "data" => $_POST, -// "isOk" => false -// ], 320), 'alipay_sync_notify_fail', true); -// echo "fail"; -// die(); -// } -// } else { -// logger(json_encode([ -// "msg" => "异步回调驗證失败", -// "data" => $_POST, -// ], 320), 'alipay_sync_notify_verify_fail', true); -// //验证失败 -// echo "fail"; -// die(); -// } -// } catch (\Exception $e) { -// logger(json_encode([ -// "msg" => "异步回调處理异常", -// "data" => $params ?? [], -// "exception" => $e->getMessage() -// ], 320), 'alipay_sync_notify_exception', true); -// //回調異常 -// echo "fail"; -// die(); -// } -// } + exit(json_encode( + [ + "alipay_commerce_educate_facefeature_groupkey_query_response" => [ + "code" => "10000", + "msg" => "Success", + "group_key" => "K12_2088323332233424", + ]] + )); } /** diff --git a/src/common/Service/AliBPass/AliEcoService.php b/src/common/Service/AliBPass/AliEcoService.php index 2a004ee..f21c1a5 100644 --- a/src/common/Service/AliBPass/AliEcoService.php +++ b/src/common/Service/AliBPass/AliEcoService.php @@ -3,62 +3,28 @@ namespace SRVX\Service\AliBPass; use SRVX\Service\BaseService; -use AopClient; +use EcoAopClient; class AliEcoService extends BaseService { - - public $config = \AlipayConfig::class; - static private $aopClient; - - public $gatewayUrl = 'https://openapi.alipay.com/gateway.do'; - public $apiVersion = '1.0'; - public $signType = 'RSA2'; - public $postCharset = 'UTF-8'; - public $format = 'json'; - - public $serverUrl = 'https://cloudpaygw.alipay-eco.com'; - public $appId = ''; + public $serverUrl = "https://cloudpaygw.alipay-eco.com"; + public $appId = '20230803121700004722802100016020'; public $privateKey = 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCSGJ9ob4kmGy6y4YeynjKJc/LSg02EXjLErPZSfVrAOy69FTRfBDbazlxpfl6YCAxDdT5ZcspB5kS2XYOY4dmqqPmF4VywmcjmZM8IxZFl1p7YC8BOlP6JrzDPwVl3hn4z3Em1byj8ANLY/AxAaW9W43FSIX+cSfdJThTlxGcbHZFM3kqu++hgFc/E+ar1nB0garqh03ESjatO4b6tuHM57ou7M+fXsoIf3gaL1IDZpeAoRh5sLCBLIbLz55tF0DcOaFsK7NUImnabJDRtrM1IN0lDZkQYAzL+JFsAq+ncRJm60Vd1jq/pXML/cFVHQQgdnjUd2u2NJTSMiCKCftmdAgMBAAECggEARzt+LduEEXJbeJiCI1MC7QX9tSqUFyAevMpgZ6P7JZM1nLfECzfwzwqjAES/Nn1mDVYTCmXvu+XcRtadnWMxUAaHcwGIwgqZa8xnLa220OKuHETOhQIcgWFL+WAakS6gRgT4Y2BJqWV1aJqsFpPR15mZ3SO8JqXhznolsknqw8sO+DBJu+QXn1HdntSGWrLU4GblPlYAs64y/MzPMUWfA4ShDRn9MZK6ypnh2GB5ezgnFxx1jRGOy96IqikI8f+M/CVdgzErLIl+qTd/IbfL8B6Gccb4ZwimL/x1H1bqYCA6xINMZLo5eDHCvBTU4AW7sItw1Q7MQ8l3wBl7hW62gQKBgQDZT1SEaeBtOJxt3vrK7o/kCWNh/4h9oENFhDIuTvLQk9tirKw0BSiZedjbEHqnqM+bgeuvxazCp9uqoYXgC/dtIooy1P8aso+ZrroC/0vZV7TQBGBjbSSkKPn7ShZM2hfYQFpmLznwpel7KJbP6AJ8atv99wjB6uvqNf6fMU7IbQKBgQCsG3mj0amsYbS5ZQZpl2v65QnlkAxv0dxcstx15kW0hXRugLOu7EGcJNZMhO4gbn8dzMOaJANZPG1VLcFpe/QyP/AW7vDt9vTWdeQkQCD5xcXEDihLLCq0pFaSkmuOHWCI+aepSHUILlJ1P/K/5biD7MTdPg6tyLqyM+rjUd/38QKBgQCNu2fsVQHDOsEMB/qakK3YlSb0q61iAjzeAjKYcXV9BHJ6ERTfeN3Z+9asSjs1TqzZSAtoQQ1EiCaFS4P9dNCTpYttS+52gy+VlJhNjCT0RHfxlGkpb+4OA4vHkbKpvTUAHjjXnMW1ZwC5CugSAchdTXTeV1im4Yms4DqJqacwoQKBgQCocPd7An8qTDIBZMOC4oT29+TYvUO+yMkAHLmx1h4QkLCkWegB4g5QkKkAGPWp3hshAj/KA0cXthFXVUG/SGZ2K6eB+nbon1N+9cDETdM4QXzN5gE/mUlupIxqRU1ouI27YYPbJSQNTrC7OkwNzfnpe/gshEj/gr5eHHvd4UrvMQKBgD2Toow7sfpV0R9rhO8aJ9njlbH15LqUK/AotK3E7zr73Uv5j/BIKS4dVC7T56L2khEUbM/y8+Rig6CdyFf3A4i4GKfbp56Sap/Haa9OP6jfep6VW7Aa1AJxPvIPgPZ2U+EuRxrwrP1EBcL5z6Cern9c9Zzs8BPUacU+Q5e8c87W'; //企业私钥 public $alipayPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWFuSpwY/2llLhy5Hxkqcc0qQFQOvemkYOI4S43L4qArX4x+DQN1RFuvfGuwOLScBKaoDYHsu9PSoTtcIj4obhhexbWHfelcsouV7Pj4YChrOkOLHAMLDQhGRXaZyXQAJdk2DoBkJ0vBDD/b1gZT8QznPopvuT4Y0rx/a2vK+5B/XV0wUuP2PnpWoPxNSwr7neFWvUdkC7yJJg4zJ1INLYy9TgHH3LKYrsEDbQzPJyMPFhD0zDb36b62q3tQYc1w8JknS6XeXMkX1Tu4zZbAxyIiv3J1FK8y7dtoRi9gLgo0uLsXWDn5AwAlzqfOERgLMWD2r6FE8tOXVbMha6IImQIDAQAB'; //平台公钥 public $aesKey = 'HOrPS0V4BthAPfgSdbHWwy0TwPnC8TQAQZIOjc8vOzI='; //加密密钥 public function __construct() { - if ((APP_ENV == 'dev')) { - $this->serverUrl = 'https://dev-cloudpaygw.alipay-eco.com'; - } - $this->getConfig(); - $this->aopClient(); - } - - - private function aopClient() - { - if (!self::$aopClient instanceof AopClient) { - self::$aopClient = new AopClient($this->config); - } - } - - - private function getConfig() - { - $alipayConfig = new \AlipayConfig(); - $alipayConfig->setServerUrl($this->serverUrl); - $alipayConfig->setAppId($this->appId); - $alipayConfig->setPrivateKey($this->privateKey); - $alipayConfig->setFormat($this->format); - $alipayConfig->setAlipayPublicKey($this->alipayPublicKey); - $alipayConfig->setCharset($this->postCharset); - $alipayConfig->setSignType($this->signType); - $this->config = $alipayConfig; +// if ((APP_ENV == 'dev')) { +// $this->serverUrl = 'https://dev-cloudpaygw.alipay-eco.com'; +// } } /** * alipay.planet.ecocampus.api.roster.signUpInfo(签约信息同步) * @param $face_uid string 学生刷脸编号(不可修改) - * @param $parent_uid string 家长uid(可修改) 2088122417040252 + * @param $parent_uid string 家长uid(可修改) 2088122417040252 * @param $parent_logon_id string 家长支付宝账号脱敏信息(可修改) * @param $roster_name string 学生姓名(可修改) * @param $out_roster_code string 外部花名册编号(不可修改) @@ -71,22 +37,41 @@ class AliEcoService extends BaseService public function alipayPlanetEcocampusApiRosterSignUpInfo($face_uid, $parent_uid, $parent_logon_id, $roster_name, $out_roster_code, $school_code, $school_name, $face_open_status = "OFF", $scan_face_pay_status = "OFF"): array { + $privateKey = $this->privateKey; + $alipayPublicKey = $this->alipayPublicKey; + $alipayConfig = new \AlipayConfig(); + $alipayConfig->setServerUrl($this->serverUrl); //行业云接口地址 + $alipayConfig->setAppId($this->appId); //行业云上的服务商isv_app_id + $alipayConfig->setPrivateKey($privateKey); + $alipayConfig->setFormat("json"); + $alipayConfig->setAlipayPublicKey($alipayPublicKey); + $alipayConfig->setCharset("UTF-8"); + $alipayConfig->setSignType("RSA2"); + + $alipayClient = new EcoAopClient($alipayConfig); + //加密密钥,仅在接口内容需要加密时生效 + $alipayClient->encryptKey = $this->aesKey; + $alipayClient->encryptType = "AES"; + try { $request = new \AlipayPlanetEcocampusApiRosterSignUpInfo(); $params = [ "face_uid" => $face_uid, - "face_open_status" => $parent_uid, - "parent_uid" => $parent_logon_id, - "parent_logon_id" => $roster_name, - "roster_name" => $out_roster_code, - "out_roster_code" => $school_code, - "school_code" => $school_name, - "school_name" => $face_open_status, + "face_open_status" => $face_open_status, + "parent_uid" => $parent_uid, + "parent_logon_id" => $parent_logon_id, + "roster_name" => $roster_name, + "out_roster_code" => $out_roster_code, + "school_code" => $school_code, + "school_name" => $school_name, "scan_face_pay_status" => $scan_face_pay_status, ]; - $request->setBizContent(json_encode($params)); - $response = self::$aopClient->execute($request); + + //加密开关,仅在接口内容需要加密时生效 + $request->setNeedEncrypt(true); + + $response = $alipayClient->execute($request); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $responseData = json_decode(json_encode($response->$responseNode), true); if ($responseData['code'] == 10000) { diff --git a/src/common/Service/AliBPass/AliEcoServiceBack.php b/src/common/Service/AliBPass/AliEcoServiceBack.php new file mode 100644 index 0000000..8ca3d20 --- /dev/null +++ b/src/common/Service/AliBPass/AliEcoServiceBack.php @@ -0,0 +1,112 @@ +serverUrl = 'https://dev-cloudpaygw.alipay-eco.com'; + } + $this->getConfig(); + $this->aopClient(); + } + + + private function aopClient() + { + if (!self::$aopClient instanceof EcoAopClient) { + self::$aopClient = new EcoAopClient(self::$config); + self::$aopClient->appId = self::$config['ali_app_id']; + //支付宝私钥值 + self::$aopClient->rsaPrivateKey = self::$config['ali_private_key']; + //支付宝公钥值 + self::$aopClient->alipayrsaPublicKey = self::$config['ali_public_key']; + } +// self::$aopClient->gatewayUrl = $this->gatewayUrl; + self::$aopClient->gatewayUrl = $this->serverUrl; +// self::$aopClient->apiVersion = $this->apiVersion; + self::$aopClient->signType = $this->signType; + self::$aopClient->postCharset = $this->postCharset; + self::$aopClient->format = $this->format; + } + + + private function getConfig() + { + if (empty(self::$config)) { + self::$config = [ + "ali_app_id" => $this->appId, + "ali_private_key" => $this->privateKey, + "ali_public_key" => $this->alipayPublicKey + ]; + } + } + + /** + * alipay.planet.ecocampus.api.roster.signUpInfo(签约信息同步) + * @param $face_uid string 学生刷脸编号(不可修改) + * @param $parent_uid string 家长uid(可修改) 2088122417040252 + * @param $parent_logon_id string 家长支付宝账号脱敏信息(可修改) + * @param $roster_name string 学生姓名(可修改) + * @param $out_roster_code string 外部花名册编号(不可修改) + * @param $school_code string 学校内标(不可修改) + * @param $school_name string 学校名称(不可修改) + * @param $face_open_status string 刷脸开通状态(可修改) + * @param $scan_face_pay_status string 刷脸支付开通状态(可修改) + * @return array + */ + + public function alipayPlanetEcocampusApiRosterSignUpInfo($face_uid, $parent_uid, $parent_logon_id, $roster_name, $out_roster_code, $school_code, $school_name, $face_open_status = "OFF", $scan_face_pay_status = "OFF"): array + { + try { + $request = new \AlipayPlanetEcocampusApiRosterSignUpInfo(); + $params = [ + "face_uid" => $face_uid, + "face_open_status" => $parent_uid, + "parent_uid" => $parent_logon_id, + "parent_logon_id" => $roster_name, + "roster_name" => $out_roster_code, + "out_roster_code" => $school_code, + "school_code" => $school_name, + "school_name" => $face_open_status, + "scan_face_pay_status" => $scan_face_pay_status, + ]; + + $request->setBizContent(json_encode($params)); + $response = self::$aopClient->execute($request); + $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; + dd($responseNode); + $responseData = json_decode(json_encode($response->$responseNode), true); + if ($responseData['code'] == 10000) { + return $this->returnRes(true, $responseData['msg'], $responseData); + } else { + return $this->returnRes(false, ($responseData['sub_msg'] ?? $responseData['msg']), $responseData); + } + } catch (\Exception $exception) { + return $this->returnRes(false, $exception->getMessage()); + } + } + +} \ No newline at end of file diff --git a/src/common/Service/AliBPass/demo/AliEcoService.php b/src/common/Service/AliBPass/demo/AliEcoService.php new file mode 100644 index 0000000..d3cd4aa --- /dev/null +++ b/src/common/Service/AliBPass/demo/AliEcoService.php @@ -0,0 +1,167 @@ +gatewayUrl = $this->serverUrl; + $client->rsaPrivateKey = $this->privateKey; + $client->alipayrsaPublicKey = $this->alipayPublicKey; + $client->signType = $this->signType; + $client->format = $this->format; + + // 业务参数 + $bizContent["face_uid"] = $face_uid; + $bizContent["parent_uid"] = $parent_uid; + $bizContent["parentLoginId"] = $parent_logon_id; + $bizContent["roster_name"] = $roster_name; + $bizContent["out_roster_code"] = $out_roster_code; + $bizContent["school_code"] = $school_code; + $bizContent["school_name"] = $school_name; + $bizContent["face_open_status"] = $face_open_status; + $bizContent["scan_face_pay_status"] = $scan_face_pay_status; + + // 指定需要调用的service接口 + $params["service"] = "alipay.planet.ecocampus.api.roster.signUpInfo"; + $params["request_id"] = "" . uuid(); + $params["biz_content"] = json_encode($bizContent); + $params["version"] = "1.0"; + + // 其他参数 + $params["charset"] = $this->charset; + $params["isv_app_id"] = $this->appId; + $params["utc_timestamp"] = "" . msectime(); + + //获取签名 +// $sign = $client->generateSign($params, $this->signType); + + // 调用ECOAPI + $result = $client->call($params); + + var_dump($result); + + + $jsonStr = json_encode($result); + + + // 响应的签名验证 转成Array 而非 Object + $resMapData = json_decode($jsonStr, true); + + // 验签 + $verifyRes = checkResponse($resMapData, $client->alipayrsaPublicKey); + + if ($verifyRes) { + echo "响应验签成功"; + } else { + echo "响应验签失败"; + } + + return []; + } + +} + + +/** + * 验签 仅支持 RSA2 + */ +function checkResponse($res, $pubKey) +{ + + $resSignType = $res['sign_type']; + if($resSignType != "RSA2"){ + return false; + } + + $resSign = $res['sign']; + + $data = $res["response"]; + nestKsort($data); + $data = json_encode($data,JSON_UNESCAPED_UNICODE); + $data = str_replace("[]", "{}", $data); + + $pubKey = "-----BEGIN PUBLIC KEY-----\n" . + wordwrap($pubKey, 64, "\n", true) . + "\n-----END PUBLIC KEY-----"; + $pubKey = openssl_get_publickey($pubKey); + + $resSign = base64_decode($resSign); + $result = (bool)openssl_verify($data, $resSign, $pubKey, OPENSSL_ALGO_SHA256); + return $result; +} + +/** + * 返回值json字段排序 + */ +function nestKsort(&$data) +{ + foreach ($data as $key => &$item) { + if (is_array($item)) { + nestKsort($item); + } + } + ksort($data); +} + + +/** + * 返回当前的毫秒时间戳 + */ +function msectime() +{ + list($s1, $s2) = explode(' ', microtime()); + return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000); +} + +/** + * 生成UUID + */ +function uuid() +{ + $chars = md5(uniqid(mt_rand(), true)); + $uuid = substr($chars, 0, 8) . '-' + . substr($chars, 8, 4) . '-' + . substr($chars, 12, 4) . '-' + . substr($chars, 16, 4) . '-' + . substr($chars, 20, 12); + return $uuid; +} diff --git a/src/common/Service/AliBPass/demo/AopEncrypt.php b/src/common/Service/AliBPass/demo/AopEncrypt.php index 8a8be92..59af900 100644 --- a/src/common/Service/AliBPass/demo/AopEncrypt.php +++ b/src/common/Service/AliBPass/demo/AopEncrypt.php @@ -8,71 +8,71 @@ */ -/** - * 加密方法 - * @param string $str - * @return string - */ -function encrypt($str, $screct_key) -{ - //AES, 128 模式加密数据 CBC - $screct_key = base64_decode($screct_key); - $str = trim($str); - $str = 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 - */ -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 = stripPKSC7Padding($decrypt_str); - return $decrypt_str; -} - -/** - * 填充算法 - * @param string $source - * @return string - */ -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 - */ -function stripPKSC7Padding($source) -{ - $char = substr($source, -1); - $num = ord($char); - if ($num == 62) return $source; - $source = substr($source, 0, -$num); - return $source; -} \ No newline at end of file +///** +// * 加密方法 +// * @param string $str +// * @return string +// */ +//function EcoEncrypt($str, $screct_key) +//{ +// //AES, 128 模式加密数据 CBC +// $screct_key = base64_decode($screct_key); +// $str = trim($str); +// $str = 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 +// */ +//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 = stripPKSC7Padding($decrypt_str); +// return $decrypt_str; +//} +// +///** +// * 填充算法 +// * @param string $source +// * @return string +// */ +//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 +// */ +//function stripPKSC7Padding($source) +//{ +// $char = substr($source, -1); +// $num = ord($char); +// if ($num == 62) return $source; +// $source = substr($source, 0, -$num); +// return $source; +//} \ No newline at end of file diff --git a/src/common/Service/AliBPass/demo/EcoapiClient.php b/src/common/Service/AliBPass/demo/EcoApiClient.php similarity index 99% rename from src/common/Service/AliBPass/demo/EcoapiClient.php rename to src/common/Service/AliBPass/demo/EcoApiClient.php index 976708a..c0959b8 100644 --- a/src/common/Service/AliBPass/demo/EcoapiClient.php +++ b/src/common/Service/AliBPass/demo/EcoApiClient.php @@ -5,7 +5,7 @@ require_once 'EncryptParseItem.php'; require_once 'EncryptResponseData.php'; require_once 'SignData.php'; -class EcoapiClient +class EcoApiClient { //应用ID public $appId; diff --git a/src/common/Service/AliBPass/demo/EncryptParseItem.php b/src/common/Service/AliBPass/demo/EncryptParseItem.php index 199bd51..35bab6f 100644 --- a/src/common/Service/AliBPass/demo/EncryptParseItem.php +++ b/src/common/Service/AliBPass/demo/EncryptParseItem.php @@ -7,12 +7,12 @@ * Time: 下午8:55 */ -class EncryptParseItem -{ - public $startIndex; - - public $endIndex; - - public $encryptContent; - -} \ No newline at end of file +//class EncryptParseItem +//{ +// public $startIndex; +// +// public $endIndex; +// +// public $encryptContent; +// +//} \ No newline at end of file diff --git a/src/common/Service/AliBPass/demo/EncryptResponseData.php b/src/common/Service/AliBPass/demo/EncryptResponseData.php index 9c394de..8502efd 100644 --- a/src/common/Service/AliBPass/demo/EncryptResponseData.php +++ b/src/common/Service/AliBPass/demo/EncryptResponseData.php @@ -7,10 +7,10 @@ * Time: 下午8:51 */ -class EncryptResponseData -{ - public $realContent; - - public $returnContent; - -} \ No newline at end of file +//class EncryptResponseData +//{ +// public $realContent; +// +// public $returnContent; +// +//} \ No newline at end of file diff --git a/src/common/Service/AliBPass/demo/SignData.php b/src/common/Service/AliBPass/demo/SignData.php index bb9ad55..44e6c62 100644 --- a/src/common/Service/AliBPass/demo/SignData.php +++ b/src/common/Service/AliBPass/demo/SignData.php @@ -6,10 +6,10 @@ * Time: 下午6:21 */ -class SignData -{ - public $signSourceData = null; - - public $sign = null; - -} \ No newline at end of file +//class SignData +//{ +// public $signSourceData = null; +// +// public $sign = null; +// +//} \ No newline at end of file diff --git a/src/common/Service/AliBPass/demo/test/Demo.php b/src/common/Service/AliBPass/demo/test/Demo.php index d6c94cc..bfcf469 100644 --- a/src/common/Service/AliBPass/demo/test/Demo.php +++ b/src/common/Service/AliBPass/demo/test/Demo.php @@ -1,9 +1,9 @@ gatewayUrl = 'http://dev-apigw.alipay-eco.com'; $client->rsaPrivateKey = '更换为应用私钥'; diff --git a/src/common/Service/Pay/AlipayK12Service.php b/src/common/Service/Pay/AlipayK12Service.php index d353880..bc48e96 100644 --- a/src/common/Service/Pay/AlipayK12Service.php +++ b/src/common/Service/Pay/AlipayK12Service.php @@ -179,4 +179,32 @@ class AlipayK12Service extends BaseService } } + /** + * alipay.commerce.educate.facepay.apply(人脸开通支付申请) + * @param $school_stdcode string 学校外标 + * @return array + */ + public function alipayCommerceEducateFaceFeatureGroupKeyQuery($school_stdcode): array + { + try { + $request = new \AlipayCommerceEducateFacefeatureGroupkeyQueryRequest(); + $params = [ + "school_stdcode" => $school_stdcode, + "biz_code" => "SCHOOL_PAYMENT", + ]; + $request->setBizContent(json_encode($params)); + $response = self::$aopClient->execute($request, null); + $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; + $responseData = json_decode(json_encode($response->$responseNode), true); +// dd($responseData); + if ($responseData['code'] == 10000) { + return $this->returnRes(true, $responseData['msg'], $responseData); + } else { + return $this->returnRes(false, ($responseData['sub_msg'] ?? $responseData['msg']), $responseData); + } + } catch (\Exception $exception) { + return $this->returnRes(false, $exception->getMessage()); + } + } + } \ No newline at end of file diff --git a/src/vendor/alipay-sdk-php-all-master/aop/AopClient.php b/src/vendor/alipay-sdk-php-all-master/aop/AopClient.php index 29c8cad..2aa524e 100644 --- a/src/vendor/alipay-sdk-php-all-master/aop/AopClient.php +++ b/src/vendor/alipay-sdk-php-all-master/aop/AopClient.php @@ -616,7 +616,6 @@ class AopClient //返回的HTTP文本不是标准JSON或者XML,记下错误日志 if (false === $respWellFormed) { - var_dump(333); $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_RESPONSE_NOT_WELL_FORMED", $resp); return false; } diff --git a/src/vendor/alipay-sdk-php-all-master/aop/AopEncrypt256.php b/src/vendor/alipay-sdk-php-all-master/aop/AopEncrypt256.php index 503f996..b78db6a 100644 --- a/src/vendor/alipay-sdk-php-all-master/aop/AopEncrypt256.php +++ b/src/vendor/alipay-sdk-php-all-master/aop/AopEncrypt256.php @@ -5,7 +5,7 @@ * @param string $str * @return string */ -function encrypt($str, $screct_key) +function encrypt256($str, $screct_key) { //AES, 128 模式加密数据 CBC $screct_key = base64_decode($screct_key); @@ -24,7 +24,7 @@ function encrypt($str, $screct_key) * @param string $str * @return string */ -function decrypt($str, $screct_key) +function decrypt256($str, $screct_key) { //AES, 128 模式加密数据 CBC $str = base64_decode($str); diff --git a/src/vendor/alipay-sdk-php-all-master/aop/EcoAopClient.php b/src/vendor/alipay-sdk-php-all-master/aop/EcoAopClient.php new file mode 100644 index 0000000..7525d1f --- /dev/null +++ b/src/vendor/alipay-sdk-php-all-master/aop/EcoAopClient.php @@ -0,0 +1,1319 @@ +appId = $config->getAppId(); + $this->format = $config->getFormat(); + $this->gatewayUrl = $config->getServerUrl(); + $this->signType = $config->getSignType(); + $this->postCharset = $config->getCharset(); + $this->rsaPrivateKey = $config->getPrivateKey(); + $this->alipayrsaPublicKey = $config->getAlipayPublicKey(); + } + } + public function generateSign($params, $signType = "RSA") + { + $params = array_filter($params); + $params['sign_type'] = $signType; + return $this->sign($this->getSignContent($params), $signType); + } + + public function rsaSign($params, $signType = "RSA") + { + return $this->sign($this->getSignContent($params), $signType); + } + + public function getSignContent($params) + { + ksort($params); + unset($params['sign']); + + $stringToBeSigned = ""; + $i = 0; + foreach ($params as $k => $v) { + if ("@" != substr($v, 0, 1)) { + + // 转换成目标字符集 + $v = $this->characet($v, $this->postCharset); + + if ($i == 0) { + $stringToBeSigned .= "$k" . "=" . "$v"; + } else { + $stringToBeSigned .= "&" . "$k" . "=" . "$v"; + } + $i++; + } + } + + unset ($k, $v); + return $stringToBeSigned; + } + + + //此方法对value做urlencode + public function getSignContentUrlencode($params) + { + ksort($params); + + $stringToBeSigned = ""; + $i = 0; + foreach ($params as $k => $v) { + if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { + + // 转换成目标字符集 + $v = $this->characet($v, $this->postCharset); + + if ($i == 0) { + $stringToBeSigned .= "$k" . "=" . urlencode($v); + } else { + $stringToBeSigned .= "&" . "$k" . "=" . urlencode($v); + } + $i++; + } + } + + unset ($k, $v); + return $stringToBeSigned; + } + + protected function sign($data, $signType = "RSA") + { + if ($this->checkEmpty($this->rsaPrivateKeyFilePath)) { + $priKey = $this->rsaPrivateKey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + } else { + $priKey = file_get_contents($this->rsaPrivateKeyFilePath); + $res = openssl_get_privatekey($priKey); + } + + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + + if ("RSA2" == $signType) { + openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); + } else { + openssl_sign($data, $sign, $res); + } + + if (!$this->checkEmpty($this->rsaPrivateKeyFilePath)) { + openssl_free_key($res); + } + $sign = base64_encode($sign); + return $sign; + } + + /** + * RSA单独签名方法,未做字符串处理,字符串处理见getSignContent() + * @param $data 待签名字符串 + * @param $privatekey 商户私钥,根据keyfromfile来判断是读取字符串还是读取文件,false:填写私钥字符串去回车和空格 true:填写私钥文件路径 + * @param $signType 签名方式,RSA:SHA1 RSA2:SHA256 + * @param $keyfromfile 私钥获取方式,读取字符串还是读文件 + * @return string + */ + public function alonersaSign($data, $privatekey, $signType = "RSA", $keyfromfile = false) + { + + if (!$keyfromfile) { + $priKey = $privatekey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + } else { + $priKey = file_get_contents($privatekey); + $res = openssl_get_privatekey($priKey); + } + + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + + if ("RSA2" == $signType) { + openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); + } else { + openssl_sign($data, $sign, $res); + } + + if ($keyfromfile) { + openssl_free_key($res); + } + $sign = base64_encode($sign); + return $sign; + } + + + protected function curl($url, $postFields = null) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FAILONERROR, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $postBodyString = ""; + $encodeArray = Array(); + $postMultipart = false; + + + if (is_array($postFields) && 0 < count($postFields)) { + + foreach ($postFields as $k => $v) { + if ("@" != substr($v, 0, 1)) //判断是不是文件上传 + { + + $postBodyString .= "$k=" . urlencode($this->characet($v, $this->postCharset)) . "&"; + $encodeArray[$k] = $this->characet($v, $this->postCharset); + } else //文件上传用multipart/form-data,否则用www-form-urlencoded + { + $postMultipart = true; + $encodeArray[$k] = new \CURLFile(substr($v, 1)); + } + + } + unset ($k, $v); + curl_setopt($ch, CURLOPT_POST, true); + if ($postMultipart) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray); + } else { + curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1)); + } + } + + if (!$postMultipart) { + $headers = array('content-type: application/x-www-form-urlencoded;charset=' . $this->postCharset); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + } + + $reponse = curl_exec($ch); + + if (curl_errno($ch)) { + + throw new \Exception(curl_error($ch), 0); + } else { + $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (200 !== $httpStatusCode) { + throw new \Exception($reponse, $httpStatusCode); + } + } + + curl_close($ch); + return $reponse; + } + + protected function getMillisecond() + { + list($s1, $s2) = explode(' ', microtime()); + return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000); + } + + + protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt) + { + $logData = array( + date("Y-m-d H:i:s"), + $apiName, + $this->appId, + PHP_OS, + $this->alipaySdkVersion, + $requestUrl, + $errorCode, + str_replace("\n", "", $responseTxt) + ); + + echo json_encode($logData); + } + + /** + * 生成用于调用收银台SDK的字符串 + * @param $request SDK接口的请求参数对象 + * @param $appAuthToken 三方应用授权token + * @return string + */ + public function sdkExecute($request, $appAuthToken = null) + { + + $this->setupCharsets($request); + + $params['app_id'] = $this->appId; + $params['method'] = $request->getApiMethodName(); + $params['format'] = $this->format; + $params['sign_type'] = $this->signType; + $params['timestamp'] = date("Y-m-d H:i:s"); + $params['alipay_sdk'] = $this->alipaySdkVersion; + $params['charset'] = $this->postCharset; + + $version = $request->getApiVersion(); + $params['version'] = $this->checkEmpty($version) ? $this->apiVersion : $version; + + if ($notify_url = $request->getNotifyUrl()) { + $params['notify_url'] = $notify_url; + } + + $params['app_auth_token'] = $appAuthToken; + + $dict = $request->getApiParas(); + $params['biz_content'] = $dict['biz_content']; + + ksort($params); + + $params['sign'] = $this->generateSign($params, $this->signType); + + foreach ($params as &$value) { + $value = $this->characet($value, $params['charset']); + } + + return http_build_query($params); + } + + /** + * 页面提交执行方法 + * @param $request 跳转类接口的request + * @param string $httpmethod 提交方式,两个值可选:post、get; + * @param null $appAuthToken 三方应用授权token + * @return 构建好的、签名后的最终跳转URL(GET)或String形式的form(POST) + * @throws Exception + */ + public function pageExecute($request, $httpmethod = "POST", $appAuthToken = null) + { + + $this->setupCharsets($request); + + if (strcasecmp($this->fileCharset, $this->postCharset)) { + + // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为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"); + $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(); + } + if (!$this->checkEmpty($request->getReturnUrl())) { + $sysParams["return_url"] = $request->getReturnUrl(); + } + $sysParams["charset"] = $this->postCharset; + if (!$this->checkEmpty($appAuthToken)) { + $sysParams["app_auth_token"] = $appAuthToken; + } + + //获取业务参数 + $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($apiParams['biz_content'], $this->encryptKey); + $apiParams['biz_content'] = $enCryptContent; + + } + + //print_r($apiParams); + $totalParams = array_merge($apiParams, $sysParams); + + //待签名字符串 + $preSignStr = $this->getSignContent($totalParams); + + //签名 + $totalParams["sign"] = $this->generateSign($totalParams, $this->signType); + + if ("GET" == strtoupper($httpmethod)) { + + //value做urlencode + $preString = $this->getSignContentUrlencode($totalParams); + //拼接GET请求串 + $requestUrl = $this->gatewayUrl . "?" . $preString; + + return $requestUrl; + } else { + //拼接表单字符串 + return $this->buildRequestForm($totalParams); + } + + + } + + + /** + * 建立请求,以表单HTML形式构造(默认) + * @param $para_temp 请求参数数组 + * @return 提交表单HTML文本 + */ + protected function buildRequestForm($para_temp) + { + + $sHtml = "
"; + + $sHtml = $sHtml . ""; + + return $sHtml; + } + + protected function fun_adm_each(&$array) + { + $res = array(); + $key = key($array); + if ($key !== null) { + next($array); + $res[1] = $res['value'] = $array[$key]; + $res[0] = $res['key'] = $key; + } else { + $res = false; + } + return $res; + } + + + public function execute($request, $authToken = null, $appInfoAuthtoken = null, $targetAppId = null) + { + + $this->setupCharsets($request); + + //如果两者编码不一致,会出现签名验签或者乱码 + if (strcasecmp($this->fileCharset, $this->postCharset)) { + + // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为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($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 . "//IGNORE", $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) { + var_dump(333); + $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 . "//IGNORE", $resp); + $respObject = json_decode($r); + } else { + + $resp = $this->encryptXMLSignSource($request, $resp); + + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + $disableLibxmlEntityLoader = libxml_disable_entity_loader(true); + $respObject = @ simplexml_load_string($r); + libxml_disable_entity_loader($disableLibxmlEntityLoader); + + } + } + + return $respObject; + } + + /** + * 转换字符集编码 + * @param $data + * @param $targetCharset + * @return string + */ + function characet($data, $targetCharset) + { + + if (!empty($data)) { + $fileType = $this->fileCharset; + if (strcasecmp($fileType, $targetCharset) != 0) { + $data = mb_convert_encoding($data, $targetCharset, $fileType); + // $data = iconv($fileType, $targetCharset.'//IGNORE', $data); + } + } + + + return $data; + } + + public function exec($paramsArray) + { + if (!isset ($paramsArray["method"])) { + trigger_error("No api name passed"); + } + $inflector = new LtInflector; + $inflector->conf["separator"] = "."; + $requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request"; + if (!class_exists($requestClassName)) { + trigger_error("No such api: " . $paramsArray["method"]); + } + + $session = isset ($paramsArray["session"]) ? $paramsArray["session"] : null; + + $req = new $requestClassName; + foreach ($paramsArray as $paraKey => $paraValue) { + $inflector->conf["separator"] = "_"; + $setterMethodName = $inflector->camelize($paraKey); + $inflector->conf["separator"] = "."; + $setterMethodName = "set" . $inflector->camelize($setterMethodName); + if (method_exists($req, $setterMethodName)) { + $req->$setterMethodName ($paraValue); + } + } + return $this->execute($req, $session); + } + + /** + * 校验$value是否非空 + * if not set ,return true; + * if is null , return true; + **/ + protected function checkEmpty($value) + { + if (!isset($value)) + return true; + if ($value === null) + return true; + if (trim($value) === "") + return true; + + return false; + } + + /** rsaCheckV1 & rsaCheckV2 + * 验证签名 + * 在使用本方法前,必须初始化AopClient且传入公钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaCheckV1($params, $rsaPublicKeyFilePath, $signType = 'RSA') + { + $sign = $params['sign']; + unset($params['sign']); + unset($params['sign_type']); + return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); + } + + public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType = 'RSA') + { + $sign = $params['sign']; + unset($params['sign']); + return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); + } + + function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') + { + + if ($this->checkEmpty($this->alipayPublicKey)) { + + $pubKey = $this->alipayrsaPublicKey; + $res = "-----BEGIN PUBLIC KEY-----\n" . + wordwrap($pubKey, 64, "\n", true) . + "\n-----END PUBLIC KEY-----"; + } else { + //读取公钥文件 + $pubKey = file_get_contents($rsaPublicKeyFilePath); + //转换为openssl格式密钥 + $res = openssl_get_publickey($pubKey); + } + + ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); + + //调用openssl内置方法验签,返回bool值 + + $result = FALSE; + if ("RSA2" == $signType) { + $result = (openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256) === 1); + } else { + $result = (openssl_verify($data, base64_decode($sign), $res) === 1); + } + + if (!$this->checkEmpty($this->alipayPublicKey)) { + //释放资源 + openssl_free_key($res); + } + + return $result; + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function checkSignAndDecrypt($params, $rsaPublicKeyPem, $rsaPrivateKeyPem, $isCheckSign, $isDecrypt, $signType = 'RSA') + { + $charset = $params['charset']; + $bizContent = $params['biz_content']; + if ($isCheckSign) { + if (!$this->rsaCheckV2($params, $rsaPublicKeyPem, $signType)) { + echo "