一、福祿平臺介紹 產品介紹 開放平臺提供專業的數字權益商品標準化介面和免費接入服務,數字權益商品涵蓋話費、流量、游戲、Q幣、視頻會員、加油卡、禮品卡等多種品類,可滿足使用者多方面的業務需求,豐富企業的產品內容、提升競爭優勢。 產品功能 商品管理:提供API商戶可以進行對接的商品類目和編號。 訂單管理 ...
一、福祿平臺介紹
產品介紹
開放平臺提供專業的數字權益商品標準化介面和免費接入服務,數字權益商品涵蓋話費、流量、游戲、Q幣、視頻會員、加油卡、禮品卡等多種品類,可滿足使用者多方面的業務需求,豐富企業的產品內容、提升競爭優勢。
產品功能
- 商品管理:提供API商戶可以進行對接的商品類目和編號。
- 訂單管理:訂單明細查詢、充值記錄核對等。
- 應用配置:密鑰管理、賬號綁定、IP白名單添加、參數配置。
使用場景
擁有一定技術團隊的企業,接入充值API,用於手機App、PC客戶端、微信公眾號、小程式、支付寶生活號等多種場景,為自己的用戶提供線上充值服務,豐富服務內容,促進流量變現。
產品優勢
- 介面穩定性高,充值秒到賬:專業技術團隊保證介面安全、穩定,用戶從下單到充值成功僅需3秒。
- 貨源豐富,涵蓋全品類:多達千種數字權益商品,全品類覆蓋,可滿足不同行業、不同場景需求。
- 強勢資源,保障低價:憑藉雄厚資金實力,整合行業優勢資源,與超過20個總代品牌合作,保障產品優質低價。
業務場景
手冊地址
- 文檔地址:
https://docs.open.fulu.com/home
- 接入說明:
https://docs.open.fulu.com/apiDocument?productSolutionId=86ce7354-c80f-42df-8043-7aaf4b1d7d68&id=30bc78e4-1d39-4496-8cbc-d6ca840926c3
- 沙箱測試:
https://docs.open.fulu.com/apitest?catalogueId=52615a59-7362-4f17-86b4-7fbccd310c7d&menuClass=%E5%95%86%E5%93%81API
二、 PHP代碼封裝
<?php /** * Created by PhpStrom * @author: 劉陽<[email protected]> * User: LiuYang * Date: 2023/8/24 * Time: 14:39 */ /** * Class ThirdPartyService * 調用第三方服務 * 使用方式: * (new ThirdPartyService) * ->setApiUrl("https://www.baidu.com") // 設置地址 * ->setMethod() // 設置請求方式 * ->setHeaders() // 設置header頭 * ->sendRequest(); // 發送請求 */ class ThirdPartyService { private $apiUrl; private $method = 'POST'; private $headers = []; private $proxy; public function __construct() {} /** * 設置第三方請求地址 * @param string $apiUrl */ public function setApiUrl(string $apiUrl){ $this->apiUrl = $apiUrl; } /** * 設置請求方式 * @param string $method */ public function setMethod(string $method){ if(in_array($method,['GET', 'POST', 'PUT', 'DELETE'])){ $this->method = $method; } } /** * 設置請求頭 * @param array $headers array( 'Content-Type: application/json', 'Authorization: Bearer your-token' ) */ public function setHeaders(array $headers){ $this->headers = $headers; } /** * 設置請求代理地址 * @param string $proxy */ public function setProxy(string $proxy){ $this->proxy = $proxy; } /** * 請求第三方服務 * @param array $requestData * @param object $obj * @param string $fun * @return mixed */ public function sendRequest(array $requestData, object $obj, string $fun = 'commonParam') { // 構建請求參數 $requestParams = ($obj)->$fun($requestData); // 發送請求 $response = $this->makeRequest($this->apiUrl, $requestParams); // 處理響應 $responseData = $this->processResponse($response); return $responseData; } /** * 發起請求 * @param string $url * @param array $params * @return bool|string */ private function makeRequest(string $url, array $params) { // 發送 HTTP 請求,可以使用 cURL 或其他 HTTP 請求庫 // 假設使用 cURL 發送請求 $ch = curl_init(); if ($this->headers) { // 若 $headers 存在,則設置為請求頭 curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $url); // 添加請求地址 if ($this->method == 'GET') { $urlParamStr = $this->getParamStr($params); } elseif ($this->method == 'POST') { $urlParamStr = $this->getParamStr($params, 2); curl_setopt($ch, CURLOPT_TIMEOUT, 3); // 設置3秒超時限制防止死迴圈 }else{ $urlParamStr = $params; } curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method);// 請求方式 'GET', 'POST', 'PUT', 'DELETE' // curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $urlParamStr); // 提交的數據包 if($this->proxy){ curl_setopt($ch, CURLOPT_PROXY, $this->proxy);// 請求代理 'http://proxy.example.com:8080' } $response = curl_exec($ch); // 請求執行 // 處理請求中的錯誤 if (curl_errno($ch)) { return json_encode(['code' => curl_errno($ch), 'msg' => curl_error($ch), 'data' => $response], JSON_UNESCAPED_UNICODE); } curl_close($ch); // 關閉cURL請求 return $response; } /** * 處理響應數據 * @param $response * @return mixed */ private function processResponse($response) { // 處理響應數據,根據實際情況解析 JSON、XML 等格式的數據 // 假設響應數據是 JSON 格式 $responseData = json_decode($response, true); return $responseData; } /** * @param array $params 參數數組 * @param int $type 參數構造類型:1:queryString 2:json * @return string */ private function getParamStr(array $params, int $type):string { if (!$params) { return ''; } $paramStr = ''; if ($type == 1) { $paramArr = []; foreach ($params as $filed => $val) { $paramArr[] = $filed . '=' . $val; } $paramStr = implode('&', $paramArr); } elseif ($type == 2) { $paramStr = json_encode($params, true); } return $paramStr; } } /** * Class Common * 定義公共參數 */ class Common{ // 福祿網路-AppKey const FU_LU_APP_KEY = 'i4esv1l+76l/7NQCL3QudG90Fq+YgVfFGJAWgT+7qO1Bm9o/adG/1iwO2qXsAXNB'; // 福祿網路-AppSecret const FU_LU_APP_SECRET = '0a091b3aa4324435aab703142518a8f7'; // 福祿網路-MemberCode const FU_LU_MEMBER_CODE = '9000358'; // 測試/生產環境IP:47.110.196.112、118.31.170.160 const FU_LU_URL = 'https://pre-openapi.fulu.com/api/getway'; // 福祿網路-錯誤碼-自定義錯誤碼替換福祿平臺狀態嗎 const FU_LU_RET_DIC = [ 0 => ['code' => 0, 'msg' => '介面調用成功',], 1000 => ['code' => 100071000, 'msg' => '必須傳入API介面名稱',], 1001 => ['code' => 100071001, 'msg' => '無效的API介面名稱',], 1002 => ['code' => 100071002, 'msg' => '必須傳入時間戳',], 1003 => ['code' => 100071003, 'msg' => '時間戳格式錯誤',], 1004 => ['code' => 100071004, 'msg' => '時間戳已超過有效期',], 1005 => ['code' => 100071005, 'msg' => '必須傳入app_key',], 1006 => ['code' => 100071006, 'msg' => '無效的app_key',], 1007 => ['code' => 100071007, 'msg' => '必須傳入版本號',], 1008 => ['code' => 100071008, 'msg' => '版本號錯誤',], 1009 => ['code' => 100071009, 'msg' => '必須傳入format格式',], 1010 => ['code' => 100071010, 'msg' => 'format格式錯誤',], 1011 => ['code' => 100071011, 'msg' => '必須傳入編碼格式',], 1012 => ['code' => 100071012, 'msg' => '編碼格式錯誤',], 1013 => ['code' => 100071013, 'msg' => '必須傳入簽名加密類型',], 1014 => ['code' => 100071014, 'msg' => '簽名加密類型錯誤',], 1015 => ['code' => 100071015, 'msg' => '必須傳入簽名',], 1016 => ['code' => 100071016, 'msg' => '簽名錯誤',], 1017 => ['code' => 100071017, 'msg' => '必須傳入請求參數集合',], 1018 => ['code' => 100071018, 'msg' => '缺少必要參數',], 1019 => ['code' => 100071019, 'msg' => '訪問IP不在IP白名單內',], 2000 => ['code' => 100072000, 'msg' => '商戶不存在',], 2001 => ['code' => 100072001, 'msg' => '商戶已被禁用',], 2002 => ['code' => 100072002, 'msg' => '無效的商戶或應用',], 2003 => ['code' => 100072003, 'msg' => '商戶或應用配置異常',], 2004 => ['code' => 100072004, 'msg' => '商戶餘額不足',], 2114 => ['code' => 100072114, 'msg' => '必須傳入對賬單獲取單號',], 2115 => ['code' => 100072115, 'msg' => '必須傳入對賬單主題',], 2116 => ['code' => 100072116, 'msg' => '對賬單主題格式錯誤',], 2117 => ['code' => 100072117, 'msg' => '必須傳入賬單類型',], 2118 => ['code' => 100072118, 'msg' => '賬單類型錯誤',], 2119 => ['code' => 100072119, 'msg' => '對賬單excel列頭錯誤',], 2120 => ['code' => 100072120, 'msg' => '必須傳入開始時間和結束時間',], 2121 => ['code' => 100072121, 'msg' => '開始時間或結束時間錯誤',], 3000 => ['code' => 100073000, 'msg' => '必須傳入商品編號',], 3001 => ['code' => 100073001, 'msg' => '商品不存在或無法購買',], 3002 => ['code' => 100073002, 'msg' => '商品已下架',], 3003 => ['code' => 100073003, 'msg' => '商品維護中',], 3004 => ['code' => 100073004, 'msg' => '商品在維護期內',], 3005 => ['code' => 100073005, 'msg' => '商品庫存不足',], 3006 => ['code' => 100073006, 'msg' => '必須傳入商品模板編號',], 3007 => ['code' => 100073007, 'msg' => '商品模板不存在',], 3008 => ['code' => 100073008, 'msg' => '商品類型錯誤',], 3009 => ['code' => 100073009, 'msg' => '商品異常,商品庫存狀態無法查詢',], 4000 => ['code' => 100074000, 'msg' => '必須傳入外部訂單號',], 4001 => ['code' => 100074001, 'msg' => '購買數量必須大於0',], 4002 => ['code' => 100074002, 'msg' => '必須傳入充值賬號',], 4003 => ['code' => 100074003, 'msg' => '充值賬號不是手機號',], 4004 => ['code' => 100074004, 'msg' => '充值賬號在黑名單中',], 4005 => ['code' => 100074005, 'msg' => '充值面值(數額)必須大於0',], 4008 => ['code' => 100074008, 'msg' => '添加訂單失敗',], 4009 => ['code' => 100074009, 'msg' => '執行下單超時,請查單確認下單結果',], 4010 => ['code' => 100074010, 'msg' => '外部訂單號已存在',], 4011 => ['code' => 100074011, 'msg' => '訂單不存在',], 4012 => ['code' => 100074012, 'msg' => '查詢異常,請重試',], 5000 => ['code' => 100075000, 'msg' => '系統異常,訂單可疑',], 5001 => ['code' => 100075001, 'msg' => '系統異常',], ]; // 福祿網路-API介面地址 const FU_LU_REQUEST_URI = [ 101 => 'fulu.user.info.get', //獲取用戶信息介面 201 => 'fulu.goods.list.get', //獲取商品列表介面 202 => 'fulu.goods.info.get', //獲取商品信息介面 203 => 'fulu.goods.template.get', //獲取商品模板介面 204 => 'fulu.goods.stock.check', //商品庫存校驗介面 301 => 'fulu.order.direct.add', //直充下單介面 302 => 'fulu.order.card.add', //卡密下單介面 303 => 'fulu.order.mobile.add', //話費下單介面 304 => 'fulu.order.info.get', //訂單查詢介面 305 => 'fulu.order.extend.get', //訂單擴展信息查詢介面 306 => 'fulu.order.record.get', //對賬單申請介面 401 => 'fulu.alipay.applet.pay', //支付寶小程式支付介面 402 => 'fulu.alipay.app.pay', //支付寶App支付介面 403 => 'fulu.alipay.h5.pay', //支付寶H5支付介面 404 => 'fulu.alipay.h5.query', //支付寶查單介面 405 => 'fulu.alipay.h5.refund', //支付寶退款介面 406 => 'fulu.alipay.refund.query', //支付寶退款查詢介面 411 => 'fulu.wechatpay.applet.pay', //微信小程式支付介面 412 => 'fulu.wechatpay.h5.pay', //微信H5支付介面 413 => 'fulu.wechatpay.h5.query', //微信查單介面 414 => 'fulu.wechatpay.h5.refund', //微信退款介面 415 => 'fulu.wechatpay.refund.query', //微信退款查詢介面 501 => 'fulu.market.qqnickname.get', //QQ昵稱查詢介面 502 => 'fulu.aiqiyi.user.check', //愛奇藝用戶身份校驗介面 503 => 'fulu.mobile.maintain.check', //話費維護狀態檢查介面 504 => 'fulu.mobile.info.get', //手機號歸屬地介面 ]; } /** * Class FuLuAPi * 福祿網路介面類封裝 */ class FuLuAPi{ private $methodUri; /** * 設置介面地址 * @param string $methodUri 'fulu.goods.list.get' */ public function setMethodUri(string $methodUri){ $this->methodUri = $methodUri; } /** * 福祿網路簽名 * @param $params * @return string */ private function getSign(array $params):string { //簽名步驟一:把字典json序列化 $json = json_encode( $params, 320 ); //簽名步驟二:轉化為數組 $jsonArr = $this->mb_str_split( $json ); //簽名步驟三:排序 sort( $jsonArr ); //簽名步驟四:轉化為字元串 $string = implode( '', $jsonArr ); //簽名步驟五:在string後加入secret $string = $string . Common::FU_LU_APP_SECRET; //簽名步驟六:MD5加密 $result_ = strtolower( md5( $string ) ); return $result_; } /** * 可將字元串中中文拆分成字元數組 */ private function mb_str_split($str){ return preg_split('/(?<!^)(?!$)/u', $str ); } /** * 獲取福祿請求參數 * @param array $bizContentArr * @return string[] */ public function commonParam( array $bizContentArr){ $bizContent = $bizContentArr ? json_encode($bizContentArr, true) : '{}'; $data = [ // @todo 福祿網路 'app_key' => Common::FU_LU_APP_KEY, 'method' => $this->methodUri,//'fulu.goods.list.get' 'timestamp' => date('Y-m-d H:i:s', time()), 'version' => '2.0', 'format' => 'json', 'charset' => 'utf-8', 'sign_type' => 'md5', 'app_auth_token' => '', 'biz_content' => $bizContent, ]; $data['sign'] = $this->getSign($data); return $data; } } /** * Class FuLu * 使用福祿網路方法的調用 */ class FuLu{ /** * @var ThirdPartyService 基礎數據 AppKey:i4esv1l+76l/7NQCL3QudG90Fq+YgVfFGJAWgT+7qO1Bm9o/adG/1iwO2qXsAXNB AppSecret:0a091b3aa4324435aab703142518a8f7 MemberCode:9000358 商戶名稱:OpenApi2.0對接專用商戶 測試/生產環境IP:47.110.196.112、118.31.170.160 直充介面相關 測試商品: 1、10000586 視頻/文娛直充測試商品-返回充值成功 2、10000585 視頻/文娛直充測試商品-返回充值失敗 3、10000586 網游直充測試商品(不帶區服)-返回充值成功 4、10000585 網游直充測試商品(不帶區服)-返回充值失敗 5、10000589 網游直充測試商品(帶區服)-返回充值成功 6、10000588 網游直充測試商品(帶區服)-返回充值失敗 7、10000000 視頻/文娛直充測試商品-介面請求失敗 錯誤碼:3001(商品不存在或無法購買) 8、12080016 視頻/文娛直充測試商品-介面請求失敗 錯誤碼:3002(商品已下架) 註意:直充類訂單需按照對應商品才能返回“充值成功”、“充值失敗”狀態。 卡密介面相關 測試商品: 1、10000587 卡密測試商品-返回卡號、字元串卡密 2、11865227 卡密測試商品-返回卡號、鏈接卡密 3、15325315 卡密測試商品-返回無卡號、字元串卡密 4、11209851 卡密測試商品-返回無卡號、鏈接卡密 話費介面相關 手機賬號:15972368779 面值:100 註:此賬號+面值下單,訂單狀態預設返回“充值成功”狀態。 手機賬號:15972368779 面值:50 註:此賬號+面值下單,訂單狀態預設返回“充值失敗”狀態。 流量介面相關 手機賬號:15972368779 流量大小:1024 流量性質:4 註:此賬號+流量大小+流量性質下單,訂單狀態預設返回“充值成功”狀態。 手機賬號:13971553804 流量大小:1024 流量性質:4 註:此賬號+流量大小+流量性質下單,訂單狀態預設返回“充值失敗”狀態。 文檔地址:https://docs.open.fulu.com/home * 產品介紹:https://docs.open.fulu.com/apiDocument?productSolutionId=86ce7354-c80f-42df-8043-7aaf4b1d7d68&id=276259e0-7508-4721-a51b-a0de43998966 * */ private $thirdObj; private $thisObj; const RET_ORDER_STATUS = [ 'failed' => [ 'code' => 0, 'msg' => "充值失敗", // 充值失敗 'state' => "failed", ], 'untreated' => [ 'code' => 101, 'msg' => "未處理", // 未處理 'state' => "untreated", ], 'success' => [ 'code' => 0, 'msg' => "充值成功", // 充值成功 'state' => "success", ], 'processing' => [ 'code' => 102, 'msg' => "處理中", // 處理中 'state' => "processing", ], ]; public function __construct(){ // 設置當前時區 ini_set('date.timezone','PRC'); // 創建 ThirdPartyService 實例 $this->thirdObj = new ThirdPartyService(); // 設置請求地址 $this->thirdObj->setApiUrl(Common::FU_LU_URL); // 設置請求頭 $this->thirdObj->setHeaders(['Content-Type: application/json']); // 設置福祿網路請求 $this->thisObj = new FuLuAPi; } /** * 獲取用戶信息 * @return array|mixed */ public function user_info_get(){ // 設置介面地址 $this->thisObj->setMethodUri(Common::FU_LU_REQUEST_URI[101]); // 發送請求並獲取響應 $requestData = array( // 請求數據 ); $responseData = $this->thirdObj->sendRequest($requestData, $this->thisObj); // 校驗錯誤碼,如果存在錯誤信息,拋出自定義信息 if($responseData["code"]){ return Common::FU_LU_RET_DIC[$responseData["code"]]; } //如果返回成功,處理返回的數據result欄位 $responseData["result"] = json_decode($responseData["result"], true); // 處理響應數據 return $responseData; } /** * 獲取商品列表 * @return array|mixed */ public function goods_list_get(){ // 設置介面地址 $this->thisObj->setMethodUri(Common::FU_LU_REQUEST_URI[201]); // 發送請求並獲取響應 $requestData = array( // 請求數據 ); $responseData = $this->thirdObj->sendRequest($requestData, $this->thisObj); // 校驗錯誤碼,如果存在錯誤信息,拋出自定義信息 if($responseData["code"]){ return Common::FU_LU_RET_DIC[$responseData["code"]]; } //如果返回成功,處理返回的數據result欄位 $responseData["result"] = json_decode($responseData["result"], true); // 處理響應數據 return $responseData; } /** * 獲取商品詳情 * @param int $productId 10000415 * 測試成功的商品:10000413,10000415,10000416,10000420,10000422,10000423,10000426,10000430 * 10000000 視頻/文娛直充測試商品-介面請求失敗 錯誤碼:3001(商品不存在或無法購買) * 12080016 視頻/文娛直充測試商品-介面請求失敗 錯誤碼:3002(商品已下架) * @return array|mixed * stock_status 庫存狀態:斷貨、警報、充足(商品介面顯示的商品都是非斷貨狀態的商品,斷貨商品會自動下架) * sales_status 銷售狀態:下架、上架、維護中、庫存維護(商品信息介面顯示的商品都是上架狀態的商品) */ public function goods_info_get(int $productId){ // 設置介面地址 $this->thisObj->setMethodUri(Common::FU_LU_REQUEST_URI[202]); // 發送請求並獲取響應 $requestData = array( // 請求數據 "product_id" => $productId,//商品編號 ); $responseData = $this->thirdObj->sendRequest($requestData, $this->thisObj); // 校驗錯誤碼,如果存在錯誤信息,拋出自定義信息 if($responseData["code"]){ return Common::FU_LU_RET_DIC[$responseData["code"]]; } //如果返回成功,處理返回的數據result欄位 $responseData["result"] = json_decode($responseData["result"], true); // 處理響應數據 return $responseData; } /** * 查詢商品庫存 * @param int $productId * @param int $num * @return array|mixed * stock_status 庫存狀態:斷貨、充足(商品介面顯示的商品都是非斷貨狀態的商品,斷貨商品會自動下架) */ public function goods_stock_check(int $productId, int $num = 1){ // 設置介面地址 $this->thisObj->setMethodUri(Common::FU_LU_REQUEST_URI[204]); // 發送請求並獲取響應 $requestData = array( // 請求數據 "buy_num" => $num,//購買數量 "product_id" => $productId,//商品編號 ); $responseData = $this->thirdObj->sendRequest($requestData, $this->thisObj); // 校驗錯誤碼,如果存在錯誤信息,拋出自定義信息 if($responseData["code"]){ return Common::FU_LU_RET_DIC[$responseData["code"]]; } //如果返回成功,處理返回的數據result欄位 $responseData["result"] = json_decode($responseData["result"], true); // 處理響應數據 return $responseData; } /** * 直衝下單介面 * @param int $productId //福祿平臺訂單號,可以從商品列表中獲取 * @param string $orderId // 外部訂單號 * @param string $mobile // 充值手機號 * @return array|mixed * order_state 訂單狀態: (success:成功,processing:處理中,failed:失敗,untreated:未處理) */ public function order_direct_add(int $productId, string $orderId, string $mobile){ // 設置介面地址 $this->thisObj->setMethodUri(Common::FU_LU_REQUEST_URI[301]); // 發送請求並獲取響應 $requestData = array( // 請求數據 "product_id" => $productId,//商品編號 "customer_order_no" => $orderId,//外部訂單號 "charge_account" => $mobile,//充值賬號 "buy_num" => "1",//購買數量 ); $responseData = $this->thirdObj->sendRequest($requestData, $this->thisObj); // 校驗錯誤碼,如果存在錯誤信息,拋出自定義信息 if($responseData["code"]){ return Common::FU_LU_RET_DIC[$responseData["code"]]; } //如果返回成功,處理返回的數據result欄位 $responseData["result"] = json_decode($responseData["result"], true); // // 處理訂單狀態,如果失敗返回訂單失敗錯誤碼 // if(self::RET_ORDER_STATUS[$responseData["result"]["order_state"]]){ // return self::RET_ORDER_STATUS[$responseData["result"]["order_state"]]; // } // 處理響應數據 return $responseData; } /** * 卡密下單介面 * 測試商品: 1、10000587 卡密測試商品-返回卡號、字元串卡密 2、11865227 卡密測試商品-返回卡號、鏈接卡密 3、15325315 卡密測試商品-返回無卡號、字元串卡密 4、11209851 卡密測試商品-返回無卡號、鏈接卡密 * @param int $productId //福祿平臺訂單號,可以從商品列表中獲取 * @param string $orderId // 外部訂單號 * @return array|mixed * order_state 訂單狀態: (success:成功,processing:處理中,failed:失敗,untreated:未處理) */ public function order_card_add(int $productId, string $orderId){ // 設置介面地址 $this->thisObj->setMethodUri(Common::FU_LU_REQUEST_URI[302]); // 發送請求並獲取響應 $requestData = array( // 請求數據 "product_id" => $productId,//商品編號 "customer_order_no" => $orderId,//外部訂單號 "buy_num" => "1",//購買數量 ); $responseData = $this->thirdObj->sendRequest($requestData, $this->thisObj); // 校驗錯誤碼,如果存在錯誤信息,拋出自定義信息 if($responseData["code"]){ return Common::FU_LU_RET_DIC[$responseData["code"]]; } //如果返回成功,處理返回的數據result欄位 $responseData["result"] = json_decode($responseData["result"], true); // // 處理訂單狀態,如果失敗返回訂單失敗