<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                對接杉德支付主要還是看人家給出的demo和文檔 以下文件都是根據官方給出的demo修改而來的 配置類 ___ ``` <?php namespace sandpay; use Exception; use think\Db; class SandConfig { //--------------------------------------------1、基礎參數配置------------------------------------------------ const API_HOST = 'https://cashier.sandpay.com.cn/gateway/api'; const PUB_KEY_PATH = __DIR__ .'/cert/sand.cer'; //公鑰文件 官網可以直接下載 const PRI_KEY_PATH = __DIR__ .'/cert/private_key.pfx'; //私鑰文件 給出的郵件里面可以使用360瀏覽器,官方推薦IE瀏覽器,具體流程可以問客服怎么導出證書,需要導出公鑰和私鑰證書文件 私鑰的在這里,公鑰的上傳到杉德支付的商服后臺。 const CERT_PWD = 123456; //私鑰證書密碼 這個秘鑰是導出私鑰的時候設置的 自定義 一定要記住密碼 const MID = '000000000'; // 商戶ID const FRONT_URL = ''; // 前端地址 // 微信appid public $wxappid=null; // 異步地址 public $notify_url=null; public function __construct() { if(is_null($this->wxappid)) $this->wxappid=Db::name('wxconfig')->where(['status'=>1])->value('appid'); if(is_null($this->notify_url)) $this->notify_url=request()->domain().'/api/order/sandNotify'; } //--------------------------------------------end基礎參數配置------------------------------------------------ /** * 獲取公鑰 * @param $path * @return mixed * @throws Exception */ public function loadX509Cert($path) { try { $file = file_get_contents($path); if (!$file) { throw new \Exception('loadx509Cert::file_get_contents ERROR'); } $cert = chunk_split(base64_encode($file), 64, "\n"); $cert = "-----BEGIN CERTIFICATE-----\n" . $cert . "-----END CERTIFICATE-----\n"; $res = openssl_pkey_get_public($cert); $detail = openssl_pkey_get_details($res); openssl_free_key($res); if (!$detail) { throw new \Exception('loadX509Cert::openssl_pkey_get_details ERROR'); } return $detail['key']; } catch (\Exception $e) { throw $e; } } /** * 獲取私鑰 * @param $path * @param $pwd * @return mixed * @throws Exception */ public function loadPk12Cert($path, $pwd) { try { $file = file_get_contents($path); if (!$file) { throw new \Exception('loadPk12Cert::file _get_contents'); } if (!openssl_pkcs12_read($file, $cert, $pwd)) { throw new \Exception('loadPk12Cert::openssl_pkcs12_read ERROR'); } return $cert['pkey']; } catch (\Exception $e) { throw $e; } } /** * 私鑰簽名 * @param $plainText * @param $path * @return string * @throws Exception */ public function sign($plainText, $path) { $plainText = json_encode($plainText); try { $resource = openssl_pkey_get_private($path); $result = openssl_sign($plainText, $sign, $resource); openssl_free_key($resource); if (!$result) { throw new \Exception('簽名出錯' . $plainText); } return base64_encode($sign); } catch (\Exception $e) { throw $e; } } /** * 公鑰驗簽 * @param $plainText * @param $sign * @param $path * @return int * @throws Exception */ public function verify($plainText, $sign, $path) { $resource = openssl_pkey_get_public($path); $result = openssl_verify($plainText, base64_decode($sign), $resource); openssl_free_key($resource); if (!$result) { throw new \Exception('簽名驗證未通過,plainText:' . $plainText . '。sign:' . $sign, '02002'); } return $result; } /** * 發送請求 * @param $url * @param $param * @return bool|mixed * @throws Exception */ public function http_post_json($url, $param) { if (empty($url) || empty($param)) { return false; } $param = http_build_query($param); try { $ch = curl_init();//初始化curl curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $param); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //正式環境時解開注釋 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); #成功連接服務器前等待時長 curl_setopt($ch, CURLOPT_TIMEOUT, 30); # 從服務器接收緩沖完成前需要等待多長時間 $data = curl_exec($ch);//運行curl curl_close($ch); if (!$data) { throw new \Exception('請求出錯'); } return $data; } catch (\Exception $e) { throw $e; } } public function parse_result($result) { $arr = array(); $response = urldecode($result); $arrStr = explode('&', $response); foreach ($arrStr as $str) { $p = strpos($str, "="); $key = substr($str, 0, $p); $value = substr($str, $p + 1); $arr[$key] = $value; } return $arr; } /** * 公鑰加密AESKey * @param $plainText * @param $puk * @return string * @throws */ public function RSAEncryptByPub($plainText, $puk) { if (!openssl_public_encrypt($plainText, $cipherText, $puk, OPENSSL_PKCS1_PADDING)) { throw new \Exception('AESKey 加密錯誤'); } return base64_encode($cipherText); } /** * 私鑰解密AESKey * @param $cipherText * @param $prk * @return string * @throws */ public function RSADecryptByPri($cipherText, $prk) { if (!openssl_private_decrypt(base64_decode($cipherText), $plainText, $prk, OPENSSL_PKCS1_PADDING)) { throw new \Exception('AESKey 解密錯誤'); } return (string)$plainText; } /** * AES加密 * @param $plainText * @param $key * @return string * @throws */ public function AESEncrypt($plainText, $key) { $plainText = json_encode($plainText); $result = openssl_encrypt($plainText, 'AES-128-ECB', $key, 1); if (!$result) { throw new \Exception('報文加密錯誤'); } return base64_encode($result); } /** * AES解密 * @param $cipherText * @param $key * @return string * @throws */ public function AESDecrypt($cipherText, $key) { $result = openssl_decrypt(base64_decode($cipherText), 'AES-128-ECB', $key, 1); if (!$result) { throw new \Exception('報文解密錯誤', 2003); } return $result; } /** * 生成AESKey * @param int $size * @return string */ public function aes_generate(int $size) { $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $arr = array(); for ($i = 0; $i < $size; $i++) { $arr[] = $str[mt_rand(0, 61)]; } return implode('', $arr); } } ``` 支付文件(直接把這個參數給前端就行 就是支付需要的參數) ___ ``` <?php namespace sandpay; use think\Request; use \sandpay\SandConfig; /** * Class Pay * @package sandpay */ class Pay{ protected static $error_info='服務器繁忙,請稍后再試!'; protected static $config=null; public function __construct() { if(self::$config == null) self::$config=new SandConfig(); } /** * 杉德支付 * @param $orderCode 商戶訂單號 * @param $money 訂單金額 * @param $userId type=1 微信 傳遞openid type=0 支付寶 userid * @param $type 1 微信 0 支付寶 * @return array * @throws \Exception */ public function start($orderCode,$money,$userId,$type=1){ // $money=0.01; // step1: 拼接data $rand=mt_rand(10,99); $data = array( 'head' => array( 'version' => '1.0', // 版本號 默認1.0 'method' => 'sandpay.trade.pay', // "請求地址-method" sandpay.trade.pay 'productId' =>$type ? '00002020' : '00002022', // 產品編碼 https://open.sandpay.com.cn/product/detail/43984// // 微信公眾號 00002020 'accessType' => '1', // 接入類型 1-普通商戶接入 2-平臺商戶接入 3-核心企業商戶接入 'mid' =>SandConfig::MID, // 商戶ID 收款方商戶號 'channelType' => '07', // 渠道類型 07-互聯網 08-移動端 'reqTime' => date('YmdHis', time()) // 請求時間 格式:yyyyMMddhhmmss ), 'body' => array( 'orderCode' =>$orderCode.$rand, // 商戶訂單號 長度12位起步,商戶唯一,建議訂單號有日期 'totalAmount' =>str_pad($money * 100,12,"0",STR_PAD_LEFT), // 訂單金額 例000000000101代表1.01元 'subject' =>'購買商品',//訂單標題 'body' =>'杉德支付',// 訂單描述 'payMode' => $type ? 'sand_wx' : 'sand_alipay',// 支付模式 sand_wx 微信公眾號/小程序支付 "payExtra"=>json_encode($type ? [ 'subAppid' => self::$config->wxappid, 'userId' => $userId ] : [ 'userId' => $userId ]),// 支付擴展域 類型為josn 'clientIp' =>request()->ip(),//客戶端IP 127.0.0.1 'notifyUrl' =>self::$config->notify_url, // 異步通知地址 1.https 2.直接可以訪問 // 'frontUrl' =>request()->domain().'/index.html#/',//前臺通知地址 'extend'=>$type, ) ); // step2: 私鑰簽名 $prikey =self::$config->loadPk12Cert(SandConfig::PRI_KEY_PATH, SandConfig::CERT_PWD); $sign = self::$config->sign($data, $prikey); // step3: 拼接post數據 $post = array( 'charset' => 'utf-8', 'signType' => '01', 'data' => json_encode($data), 'sign' => $sign ); // step4: post請求 $result =self::$config->http_post_json(SandConfig::API_HOST . '/order/pay', $post); $arr = self::$config->parse_result($result); //step5: 公鑰驗簽 $pubkey =self::$config->loadX509Cert(SandConfig::PUB_KEY_PATH); try { self::$config->verify($arr['data'], $arr['sign'], $pubkey); } catch (\Exception $e) { return $e->getMessage(); } // step6: 獲取credential $data = json_decode($arr['data'], true); if ($data['head']['respCode'] == "000000") { $datas=json_decode($data['body']['credential'],true); if(!isset($datas['params'])){ throw new \Exception("字符串解析錯誤"); } // $data = json_decode($data['params'],true); // $result = substr($data['payInfo']['trade_no'],-28,28); return json_decode($datas['params'],true); } else { return self::$error_info; } } } ``` 代付文件 ___ ``` <?php namespace sandpay; use Exception; use think\Db; use \sandpay\SandConfig; class Withdrawal { protected static $url='https://caspay.sandpay.com.cn/agent-main/openapi/agentpay'; protected static $error_info='服務器繁忙,請稍后再試!'; protected static $config=null; public function __construct() { if(self::$config == null) self::$config=new SandConfig(); } /** * 付款到銀行卡 * @param $params * @return bool */ public function start($params) { $info = array( 'transCode' => 'RTPM', // 實時代付 'merId' => SandConfig::MID, // 此處更換商戶號 'url' => '/agentpay', 'pt' => array( 'orderCode' => $params['order_sn'], 'version' => '01', 'productId' => '00000004', 'tranTime' => date('YmdHis', time()), // 'timeOut' => '20181024120000',//不填默認24小時 'tranAmt' => str_pad($params['amount'] * 100,12,"0",STR_PAD_LEFT), 'currencyCode' => '156', 'accAttr' => '0', 'accNo' => $params['bank_no'], 'accType' => '4', 'accName' => $params['bank_real_name'], // 'provNo' => 'sh', // 'cityNo' => 'sh', // 'bankName' => 'cbc',//對公代付必填 // 'bankType' => '1',//對公代付必填 'remark' => $params['bank_real_name'], 'payMode' => 'desc', 'channelType' => '07' ) ); // step1: 拼接報文及配置 $transCode = $info['transCode']; // 交易碼 $accessType = '0'; // 接入類型 0-商戶接入,默認;1-平臺接入 $merId = $info['merId']; // 此處更換商戶號 $path = $info['url']; // 服務地址 $pt = $info['pt']; // 報文 try { // step2: 生成AESKey并使用公鑰加密 $AESKey = self::$config->aes_generate(16); $pubKey = self::$config->loadX509Cert(SandConfig::PUB_KEY_PATH); $priKey = self::$config->loadPk12Cert(SandConfig::PRI_KEY_PATH,SandConfig::CERT_PWD); $encryptKey = self::$config->RSAEncryptByPub($AESKey, $pubKey); // step3: 使用AESKey加密報文 $encryptData = self::$config->AESEncrypt($pt, $AESKey); // step4: 使用私鑰簽名報文 $sign = self::$config->sign($pt,$priKey); // step5: 拼接post數據 $post = array( 'transCode' => $transCode, 'accessType' => $accessType, 'merId' => $merId, 'encryptKey' => $encryptKey, 'encryptData' => $encryptData, 'sign' => $sign ); // step6: post請求 $result = self::$config->http_post_json(self::$url, $post); parse_str($result, $arr); // step7: 使用私鑰解密AESKey $decryptAESKey = self::$config->RSADecryptByPri($arr['encryptKey'], $priKey); // step8: 使用解密后的AESKey解密報文 $decryptPlainText = self::$config->AESDecrypt($arr['encryptData'], $decryptAESKey); // step9: 使用公鑰驗簽報文 self::$config->verify($decryptPlainText, $arr['sign'],$pubKey); $decryptPlainText = json_decode($decryptPlainText,true); if((int)$decryptPlainText['respCode'] > 2 && $decryptPlainText['resultFlag'] == 1){ throw new \Exception($decryptPlainText['respDesc']); } return ['code'=>1,'info'=>'ok']; } catch (\Exception $e) { return ['code'=>0,'info'=>$e->getMessage()]; } } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看