本代码是基于天聚人合的话费充值API实现的话费充值功能,使用前需要:
- 通过https://www.tianjurenhe.com/docs/api/?id=2申请开通话费接口服务。
- 你可以在个人中心 ➡️ 数据中心 ➡️ 我的API 模块看到此接口的调用凭证请求key
- 与人合签订相关服务合同后,才能正式使用。前期您也可以申请开通测试环境,进行对接测试。
- 详细的接口说明,可参考聚合官方文档。
2.1、引入封装好的代码类
include "JuheHuaFei.class.php";
2.2、配置一些必须的参数
// 接口基本信息配置
$env = 1; // 接口环境类型,1:正式环境接口 2:测试环境接口
$appKey = 'b842820xxxxxxxxxxxxxxxxxx'; //从人合申请的话费充值接口key
$openId = 'JHb0d92d94ce6axxxxxxxxxxx'; //注册人合账号就会分配的openid,在个人中心可以查看
// 初始化
$juheHuaFei = new JuheHuaFei($appKey, $openId, $env);
2.3、提交话费充值订单
// 提交话费充值订单
$orderId = '111111111'; //自己定义一个订单号,需要保证唯一
$mobile = '189xxxxxxxx'; // 需要充值的手机号码
$perValue = '1'; // 话费面值,可以选择的面额1、2、5、10、20、30、50、100、200、300、500
$submitOrderResult = $juheHuaFei->submitOrder($mobile, $perValue, $orderId);
if ($submitOrderResult) {
if ($submitOrderResult['error_code'] == '0') {
// 订单提交成功,根据实际业务逻辑进行处理
echo "订单提交成功,订单号:" . $submitOrderResult['result']['sporder_id'];
print_r($submitOrderResult);
} else {
// 提交返回码error_code非正常状态,依据官方文档错误码说明,进行逻辑处理
// 比如:10014,系统异常 / 208516,重复的订单号 等,需要进行二次查询/人工确认处理,不要直接失败处理,避免造成不必要的损失
print_r($submitOrderResult);
}
} else {
// 可能网络异常等问题,未获得正确响应结果,建议进行二次查单/人工确认,不要直接失败处理,避免造成不必要的损失
// 依据自己的业务逻辑进行处理
echo "请求异常,请确认";
}
请求结果:
Array
(
[reason] => 订单提交成功,等待充值
[result] => Array
(
[cardid] => 10423
[cardnum] => 1
[ordercash] => 1.06
[cardname] => 江苏电信话费1元
[sporder_id] => J201125162114667xxxxxxxx
[uorderid] => 111111111
[game_userid] => 189xxxxxxxx
[game_state] => 0
)
[error_code] => 0
)
2.4、订单状态查询
除主动查询订单状态,你还可以向人合提供状态回调通知URL,订单状态有变化,人合将会主动将状态信息推送给相应的URL。
// 话费订单充值状态查询
$orderId = '111111111'; // 需要查询的订单号,即提交订单时传递的orderId
$orderStatusResult = $juheHuaFei->queryOrderStatus($orderId);
if ($orderStatusResult) {
// 打印返回结果
print_r($orderStatusResult);
// 根据实际业务逻辑进行处理
if ($orderStatusResult['error_code'] == '0') {
//查询成功
if ($orderStatusResult['result']['game_state'] == '1') {
// 订单充值成功了
echo "订单充值成功";
} elseif ($orderStatusResult['result']['game_state'] == '9') {
// 订单充值失败
echo "订单充值失败";
} elseif ($orderStatusResult['result']['game_state'] == '0') {
// 订单充值中
echo "订单充值中";
} elseif ($orderStatusResult['result']['game_state'] == '-1') {
//订单受理失败,可能是如运营商维护、账户余额不足等情况
echo "订单受理失败";
}
} else {
//查询状态失败,可能订单号不存在等情况
echo "查询失败:" . $orderStatusResult['reason'] . "(" . $orderStatusResult['error_code'] . ")";
}
} else {
// 可能网络异常等问题,未获得正确响应结果,建议进行二次查询
// 依据自己的业务逻辑进行处理
echo "请求异常,请确认";
}
返回结果:
Array
(
[reason] => 查询成功
[result] => Array
(
[uordercash] => 1.060
[sporder_id] => J2011251629516xxxxxxxxxx
[game_state] => 9
)
[error_code] => 0
)
2.5、根据手机及面额查询是否支持充值
主要通过号段进行判断是否支持充值,实际业务中可以不使用本小接口。
// 根据手机号码及面额查询是否支持充值
$mobile = '1342966xxxx'; // 手机号码
$perValue = '10'; // 话费面值,可选1、2、5、10、20、30、50、100、200、300、500
$telCheckResult = $juheHuaFei->telCheck($mobile, $perValue);
if ($telCheckResult) {
if($telCheckResult['error_code'] == '0'){
//说明支持充值,可以继续充值操作,以下可以根据实际需求修改
echo "OK";
}else{
//暂不支持充值,以下可以根据实际需求修改
echo "对不起,该面额暂不支持充值";
}
} else {
// 可能网络异常等问题,未获得正确响应结果,建议进行二次查询
// 依据自己的业务逻辑进行处理
echo "请求异常,请确认";
}
2.6、根据手机和面额获取商品信息
实际业务中可以不使用本小接口。
// 根据手机号码和面额获取商品信息
$mobile = '1342966xxxx'; // 手机号码
$perValue = '10'; // 话费面值,可选1、2、5、10、20、30、50、100、200、300、500
$telQueryResult = $juheHuaFei->telQuery($mobile, $perValue);
if ($telQueryResult) {
if($telQueryResult['error_code'] == '0'){
// 查询成功,可以根据实际逻辑修改
print_r($telQueryResult);
}else{
// 查询失败,可以根据实际逻辑修改
print_r($telQueryResult);
}
} else {
// 可能网络异常等问题,未获得正确响应结果,建议进行二次查询
// 依据自己的业务逻辑进行处理
echo "请求异常,请确认";
}
返回结果:
Array
(
[reason] => 查询成功
[result] => Array
(
[cardid] => 10880
[cardname] => 浙江移动话费10元
[inprice] => 10.2
[game_area] => 浙江杭州移动
)
[error_code] => 0
)
2.7、订单状态通知
推送URL地址:自行提供给人合进行配置 (为了更安全,你也可以将人合推送服务器的IP进行加白名单处理)
推送方式:POST
推送参数:
参数名 | 类型 | 参数说明 |
---|---|---|
sporder_id | String | 人合官方订单号 |
orderid | String | 用户自定义单号,即提交订单时传递的orderid |
sta | String | 订单状态,1:成功 9:失败 |
sign | String | 校验值,校验值,md5(appkey+sporder_id+orderid) 32位小写,用于校验请求合法性 |
PHP接收异步通知(回调)参考代码:
$appkey = "b842820xxxxxxxxxxxxxxxxxx"; //您申请的数据的APIKey
$sporder_id = addslashes($_POST['sporder_id']); //人合订单号
$orderid = addslashes($_POST['orderid']); //商户的单号
$sta = addslashes($_POST['sta']); //充值状态
$sign = addslashes($_POST['sign']); //校验值
$local_sign = md5($appkey.$sporder_id.$orderid); //本地sign校验值
if ($local_sign == $sign) {
if ($sta == '1') {
//充值成功,根据自身业务逻辑进行后续处理
} elseif ($sta =='9') {
//充值失败,根据自身业务逻辑进行后续处理
}
}
2.8、JuheHuaFei.class.php
JuheHuaFei.class.php 完整代码
<?php
//----------------------------------
// 天聚人合-手机话费充值API调用类--示例代码
// 官方接口文档:https://www.tianjurenhe.com/docs/api/?id=2
//----------------------------------
class JuheHuaFei
{
private $appkey;
private $openid;
// 提交订单接口URL
private $submitUrl;
// 订单状态查询接口URL
private $orderStatusUrl;
// 检测手机号码是否能充值URL
private $telCheckUrl;
// 根据手机号和面值查询商品URL
private $telQueryUrl;
public function __construct($appkey, $openid, $env = 1)
{
$this->appkey = $appkey; // 申请到的话费接口请求key
$this->openid = $openid; // OpenID在人合个人中心查询
if ($env == 1) {
// 正式环境,接口地址
$this->submitUrl = 'http://op.tianjurenhe.com/ofpay/mobile/onlineorder'; // 提交订单接口URL
$this->orderStatusUrl = 'http://op.tianjurenhe.com/ofpay/mobile/ordersta'; // 订单状态查询接口URL
$this->telCheckUrl = 'http://op.tianjurenhe.com/ofpay/mobile/telcheck'; // 检测手机号码是否能充值URL
$this->telQueryUrl = 'http://op.tianjurenhe.com/ofpay/mobile/telquery'; // 根据手机号和面值查询商品URL
} else {
// 测试环境,接口地址
$this->submitUrl = 'http://test-v.tianjurenhe.com/ofpay/mobile/onlineorder'; // 提交订单接口URL
$this->orderStatusUrl = 'http://test-v.tianjurenhe.com/ofpay/mobile/ordersta'; // 订单状态查询接口URL
$this->telCheckUrl = 'http://test-v.tianjurenhe.com/ofpay/mobile/telcheck'; // 检测手机号码是否能充值URL
$this->telQueryUrl = 'http://test-v.tianjurenhe.com/ofpay/mobile/telquery'; // 根据手机号和面值查询商品URL
}
}
public function submitOrder($mobile, $pervalue, $orderid)
{
$sign = md5($this->openid . $this->appkey . $mobile . $pervalue . $orderid);// 校验值计算
$params = array(
'key' => $this->appkey,
'phoneno' => $mobile,
'cardnum' => $pervalue,
'orderid' => $orderid,
'sign' => $sign
);
$content = $this->juheHttpRequest($this->submitUrl, $params, 1);
return $this->_returnArray($content);
}
public function queryOrderStatus($orderid)
{
$params = 'key=' . $this->appkey . '&orderid=' . $orderid;
$content = $this->juheHttpRequest($this->orderStatusUrl, $params);
return $this->_returnArray($content);
}
public function telCheck($mobile, $pervalue)
{
$params = 'key=' . $this->appkey . '&phoneno=' . $mobile . '&cardnum=' . $pervalue;
$content = $this->juheHttpRequest($this->telCheckUrl, $params);
return $this->_returnArray($content);
}
public function telQuery($mobile, $pervalue)
{
$params = 'key=' . $this->appkey . '&phoneno=' . $mobile . '&cardnum=' . $pervalue;
$content = $this->juheHttpRequest($this->telQueryUrl, $params);
return $this->_returnArray($content);
}
public function _returnArray($content)
{
return json_decode($content, true);
}
public function juheHttpRequest($url, $params = false, $ispost = 0)
{
$httpInfo = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_USERAGENT, 'JuheData');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($ispost) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, $url);
} else {
if ($params) {
curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
} else {
curl_setopt($ch, CURLOPT_URL, $url);
}
}
$response = curl_exec($ch);
if ($response === FALSE) {
//echo "cURL Error: " . curl_error($ch);
return false;
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$httpInfo = array_merge($httpInfo, curl_getinfo($ch));
curl_close($ch);
return $response;
}
}