| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- <?php
- namespace common\components\lakala;
- use common\components\noticeUtil;
- use common\components\stringUtil;
- class Lakala
- {
- private $appid;
- private $serial_no;
- private $merchant_no;
- private $term_no;
- private $merchantPrivateKeyPath;
- private $lklCertificatePath;
- private $schema = 'LKLAPI-SHA256withRSA';
- private $version = '3.0';
- private $preUrl = '';
- public function accountBalanceQuery()
- {
- $arr = [
- 'merchantNo' => $this->merchant_no,
- 'orgNo' => 970936,
- ];
- $rand = time() . '_' . stringUtil::charsShuffle(22);
- $baseRequestVO = [
- 'reqData' => $arr,
- 'timestamp' => time(),
- 'reqId' => $rand,
- 'ver' => '1.0.0',
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v2/laep/industry/ewalletBalanceQuery';
- return $this->post($url, $body, $authorization);
- }
- //申请主动结算 ssh
- public function applyInviteClear($params)
- {
- $subMerchantId = $params['subMerchantId'];
- $tradeMode = $params['tradeMode'];
- $arr = [
- 'tradeMode' => $tradeMode,
- 'merchantNo' => $this->merchant_no,
- 'subMerchantId' => $subMerchantId,
- 'orderNo' => $orderNo,
- //机构代号
- 'orgCode' => '970936',
- 'version' => 'v1.0.0',
- ];
- $rand = time() . '_' . stringUtil::charsShuffle(22);
- $baseRequestVO = [
- 'reqData' => $arr,
- 'timestamp' => time(),
- 'reqId' => $rand,
- 'ver' => '1.0.0',
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v2/mms/sme/mrchAuthStateQuery';
- return $this->post($url, $body, $authorization);
- }
- public function __construct($params)
- {
- $this->appid = $params['appid'] ?? '';
- $this->serial_no = $params['serial_no'] ?? '';
- $this->merchant_no = $params['merchant_no'] ?? '';
- $this->term_no = $params['term_no'] ?? '';
- $this->merchantPrivateKeyPath = $params['merchantPrivateKeyPath'];
- $this->lklCertificatePath = $params['lklCertificatePath'];
- if (getenv('YII_ENV') == 'production') {
- $this->preUrl = 'https://s2.lakala.com/api/v3/labs/trans/';
- } else {
- //$this->preUrl = 'https://test.wsmsd.cn/sit/api/v3/labs/trans/';
- $this->preUrl = 'https://s2.lakala.com/api/v3/labs/trans/';
- }
- }
- //退款查询
- public function refundQuery($params)
- {
- $orderSn = $params['orderSn'];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- //'out_trade_no' => $orderSn,
- 'trade_no' => $orderSn,
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v3/labs/query/tradequery';
- return $this->post($url, $body, $authorization);
- }
- public function openStateQuery($params)
- {
- $subMerchantId = $params['subMerchantId'];
- $tradeMode = $params['tradeMode'];
- $arr = [
- 'tradeMode' => $tradeMode,
- 'merchantNo' => $this->merchant_no,
- 'subMerchantId' => $subMerchantId,
- ];
- $baseRequestVO = [
- 'reqData' => $arr,
- 'timestamp' => time(),
- 'ver' => '1.0.0',
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v2/mms/sme/mrchAuthStateQuery';
- return $this->post($url, $body, $authorization);
- }
- //收银台支付,APP支付和H5支付时使用 ssh 2023112
- public function cashierPay($params)
- {
- $orderSn = $params['orderSn'];
- $amount = $params['amount'];
- $payWay = $params['payWay'] ?? 1;
- $payMode = $payWay==1?'ALIPAY':'WECHAT';
- $notifyUrl = $params['notifyUrl'];
- $subject = $params['subject'];
- $capitalType = $params['capitalType'];
- $time = time() + 108000;
- $orderEfficientTime = date("YmdHis", $time);
- $bus = json_encode([['busi_type' => 'SCPAY', 'params' => ['pay_mode' => $payMode]]]);
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'out_order_no' => $orderSn,
- 'total_amount' => bcmul($amount, 100),
- 'order_info' => $subject,
- 'support_refund' => 1,
- 'notify_url' => $notifyUrl,
- 'order_efficient_time' => $orderEfficientTime,
- 'busi_type_param' => $bus,
- 'counter_param' => json_encode(['pay_mode' => $payMode]),
- 'counter_remark' => '{"capitalType":' . $capitalType . '}'
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v3/ccss/counter/order/create';
- return $this->post($url, $body, $authorization);
- }
- //收银机订单查询 ssh 20231026
- public function cashierQuery($params)
- {
- $out_order_no = $params['out_order_no'];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'out_order_no' => $out_order_no,
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v3/ccss/counter/order/query';
- return $this->post($url, $body, $authorization);
- }
- public function query($params, $lklSn = 0)
- {
- $orderSn = $params['orderSn'] ?? '';
- $tradeNo = $params['tradeNo'] ?? '';
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'location_info' => $location_info,
- ];
- if ($lklSn == 0) {
- $arr['out_trade_no'] = $orderSn;
- } else {
- $arr['trade_no'] = $tradeNo;
- }
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v3/labs/query/tradequery';
- return $this->post($url, $body, $authorization);
- }
- //被扫付款
- public function scanPay($params)
- {
- $orderSn = $params['orderSn'];
- $amount = $params['amount'];
- $notifyUrl = $params['notifyUrl'];
- $subject = $params['subject'];
- $authCode = $params['authCode'];
- $capitalType = $params['capitalType'];
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'out_trade_no' => $orderSn,
- 'total_amount' => bcmul($amount, 100),
- 'auth_code' => $authCode,
- 'location_info' => $location_info,
- 'subject' => $subject,
- 'notify_url' => $notifyUrl,
- 'remark' => '{"capitalType":' . $capitalType . '}',
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $url = 'https://s2.lakala.com/api/v3/labs/trans/micropay';
- return $this->post($url, $body, $authorization);
- }
- //关掉 ssh 20231009
- public function close($params)
- {
- $orderSn = $params['orderSn'];
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'location_info' => $location_info,
- 'origin_out_trade_no' => $orderSn,
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $lklUrl = 'https://s2.lakala.com/api/v3/labs/relation/close';
- return $this->post($lklUrl, $body, $authorization);
- }
- public function cashClose($params)
- {
- $orderSn = $params['orderSn'];
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'location_info' => $location_info,
- 'out_order_no' => $orderSn,
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => '1.0',
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $lklUrl = 'https://s2.lakala.com/api/v3/ccss/counter/order/close';
- return $this->post($lklUrl, $body, $authorization);
- }
- //退款 ssh 20231009
- public function refund($params)
- {
- $orderSn = $params['orderSn'] ?? '';
- $refundSn = $params['refundSn'];
- $refundReason = $params['refundReason'];
- $refundAmount = $params['refundAmount'];
- //这个参数必传,不然聚合收银合支付宝付款的退款不会成功
- $thirdNo = $params['thirdNo'] ?? '';
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'out_trade_no' => $refundSn,
- 'refund_amount' => $refundAmount,
- 'location_info' => $location_info,
- 'refund_reason' => $refundReason,
- 'origin_out_trade_no' => $orderSn,
- 'origin_trade_no' => $thirdNo,
- ];
- //原拉卡拉交易流水号,收银台接口下单的,发起退款时必传
- if (isset($params['originTradeNo'])) {
- $arr['origin_trade_no'] = $params['originTradeNo'];
- }
- if (isset($params['originLogNo'])) {
- $arr['origin_log_no'] = $params['originLogNo'];
- }
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- $lklUrl = 'https://s2.lakala.com/api/v3/labs/relation/refund';
- return $this->post($lklUrl, $body, $authorization);
- }
- //主扫交易,微信
- public function driveWxPay($params)
- {
- $orderSn = $params['orderSn'];
- $amount = $params['amount'];
- $notifyUrl = $params['notifyUrl'];
- $subject = $params['subject'];
- $capitalType = $params['capitalType'];
- $wxAppId = $params['wxAppId'] ?? '';
- $openId = $params['openId'] ?? '';
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'out_trade_no' => $orderSn,
- 'account_type' => 'WECHAT',
- 'trans_type' => 71,
- 'total_amount' => bcmul($amount, 100),
- 'location_info' => $location_info,
- 'subject' => $subject,
- 'notify_url' => $notifyUrl,
- 'remark' => '{"capitalType":' . $capitalType . '}',
- 'acc_busi_fields' => [
- 'sub_appid' => $wxAppId,
- 'user_id' => $openId,
- 'timeout_express' => 30,
- ],
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- return $this->post($this->preUrl . 'preorder', $body, $authorization);
- }
- public function driveNativeWxPay($params)
- {
- $orderSn = $params['orderSn'];
- $amount = $params['amount'];
- $notifyUrl = $params['notifyUrl'];
- $subject = $params['subject'];
- $capitalType = $params['capitalType'];
- $wxAppId = $params['wxAppId'] ?? '';
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'out_trade_no' => $orderSn,
- 'account_type' => 'WECHAT',
- 'trans_type' => 71,
- 'total_amount' => bcmul($amount, 100),
- 'location_info' => $location_info,
- 'subject' => $subject,
- 'notify_url' => $notifyUrl,
- 'remark' => '{"capitalType":' . $capitalType . '}',
- 'acc_busi_fields' => [
- 'timeout_express' => 30,
- 'sub_appid' => $wxAppId,
- ],
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- return $this->post($this->preUrl . 'preorder', $body, $authorization);
- }
- //主扫交易,支付宝
- public function driveAliPay($params)
- {
- $orderSn = $params['orderSn'];
- $amount = $params['amount'];
- $notifyUrl = $params['notifyUrl'];
- $subject = $params['subject'];
- $capitalType = $params['capitalType'];
- $ip = $this->getClientIp();
- $location_info = ['request_ip' => $ip];
- $arr = [
- 'merchant_no' => $this->merchant_no,
- 'term_no' => $this->term_no,
- 'out_trade_no' => $orderSn,
- 'account_type' => 'ALIPAY',
- 'trans_type' => '41',
- 'total_amount' => bcmul($amount, 100),
- 'location_info' => $location_info,
- 'subject' => $subject,
- 'notify_url' => $notifyUrl,
- 'remark' => '{"capitalType":' . $capitalType . '}',
- ];
- $baseRequestVO = [
- 'req_data' => $arr,
- 'req_time' => date("YmdHis"),
- 'version' => $this->version,
- ];
- $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
- $authorization = $this->getAuthorization($body);
- return $this->post($this->preUrl . 'preorder', $body, $authorization);
- }
- //验签
- public function signatureVerification($authorization, $body)
- {
- $authorization = str_replace($this->schema . " ", "", $authorization);
- $authorization = str_replace(",", "&", $authorization);
- $authorization = str_replace("\"", "", $authorization);
- $authorization = $this->convertUrlQuery($authorization);
- $authorization['signature'] = base64_decode($authorization['signature']);
- $message = $authorization['timestamp'] . "\n" . $authorization['nonce_str'] . "\n" . $body . "\n";
- $key = openssl_get_publickey(file_get_contents($this->lklCertificatePath));
- $flag = openssl_verify($message, $authorization['signature'], $key, OPENSSL_ALGO_SHA256);
- openssl_free_key($key);
- if ($flag) {
- return true;
- }
- return false;
- }
- //签名
- public function getAuthorization($body)
- {
- $nonceStr = $this->randString(12);
- $timestamp = time();
- $message = $this->appid . "\n" . $this->serial_no . "\n" . $timestamp . "\n" . $nonceStr . "\n" . $body . "\n";
- $key = openssl_get_privatekey(file_get_contents($this->merchantPrivateKeyPath));
- openssl_sign($message, $signature, $key, OPENSSL_ALGO_SHA256);
- openssl_free_key($key);
- return $this->schema . " appid=\"" . $this->appid . "\"," . "serial_no=\"" . $this->serial_no . "\"," . "timestamp=\"" . $timestamp . "\"," . "nonce_str=\"" . $nonceStr . "\"," . "signature=\"" . base64_encode($signature) . "\"";
- }
- //获取随机数
- public function randString($length)
- {
- $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
- $randomString = "";
- for ($i = 0; $i < $length; $i++) {
- $randomString .= $characters[rand(0, strlen($characters) - 1)];
- }
- return $randomString;
- }
- //请求
- public function post($url, $data, $authorization)
- {
- $headers = [
- "Authorization: " . $authorization,
- "Accept: application/json",
- "Content-Type:application/json",
- ];
- \Yii::info("请求参数:" . $data);
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);//设置HTTP头
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_POST, 1);
- $res = curl_exec($ch);
- curl_close($ch);
- return json_decode($res, 1);
- }
- //签名参数转数组
- private function convertUrlQuery($query)
- {
- $queryParts = explode('&', $query);
- $params = array();
- foreach ($queryParts as $param) {
- $item = explode('=', $param);
- $params[$item[0]] = $item[1];
- }
- if ($params['signature']) {
- $params['signature'] = substr($query, strrpos($query, 'signature=') + 10);
- }
- return $params;
- }
- public function getClientIp()
- {
- if (isset($_SERVER['REMOTE_ADDR'])) {
- $cip = $_SERVER['REMOTE_ADDR'];
- } elseif (getenv("REMOTE_ADDR")) {
- $cip = getenv("REMOTE_ADDR");
- } elseif (getenv("HTTP_CLIENT_IP")) {
- $cip = getenv("HTTP_CLIENT_IP");
- } else {
- if (getenv('YII_ENV') == 'production') {
- $cip = "114.55.169.20";
- } else {
- $cip = "118.178.193.23";
- }
- }
- return $cip;
- }
- }
|