开发前准备
联系工行业务员开户,开户后可以得到以下参数:
appid:工商银行appid,问工行业务员提供
mer_id:工商银行商户账号,商户线下档案编号,特约商户12位,特约部门15位,问工行业务员提供
icbc_pulic_key:网关公钥,问工行业务员提供
private_key:应用私钥,用工行的工具生成,生成后自己保存
public_key:应用公钥,用工行的工具生成,生成后提供给工行业务员
encryptKey:AES加密密钥,问工行业务员提供
url:正式环境地址,问工行业务员提供,一般是https://gw.open.icbc.com.cn
以下开发将在thinkphp5
框架进行,其他php框架同理
文档和工具
-
工行聚富通api文档:工行|开放平台 (icbc.com.cn)
-
SDK和密钥生成工具:工行|开放平台 (icbc.com.cn),php版本的生成密钥好像不全,建议用java版
-
工行对客工具包:问工行提供内部调试的软件,直接解压打开
BINHELPER.exe
就能用,作用不大,不过里面有一些代码demo可以参考链接:https://pan.baidu.com/s/1tkzws5gyi1n0mN6-_ljw_A?pwd=w4ug
提取码:w4ug
下载SDK
下载sdk有两种方式:
1.官网下载
本文用这种方式,但是官方提供的sdk没有命名空间,可以借助框架加载或自己加上去,不过可能有些bug要修改才能用;
在工行|开放平台 (icbc.com.cn)页面点击sdk下载
,下载php版本。
将下载好的sdk解压到你的框架扩展目录下,以thinkphp5框架为例,将解压得到的icbc-api-sdk-cop-php
文件夹放到框架目录下的vendor
即可
注意注意:工行的sdk有坑!!!
注意注意:工行的sdk有坑!!!
注意注意:工行的sdk有坑!!!
在icbc-api-sdk-cop-php
目录下找到IcbcConstants.php
这个文件打开编辑,大概在48行,默认的时区是要修改才能用的,修改成下面的时区即可
/** Date默认时区 **/
//public static $DATE_TIMEZONE = "Etc/GMT+8";//java版GMT+8,错误的时区
public static $DATE_TIMEZONE = "Asia/Shanghai";//东八区,正确的时区
如果你的请求参数正确,工行确一直返回下图这个“参数无效或非法,请检查请求参数”很有可能是这个原因导致
2.composer安装
由于官方没有提供composer安装扩展,我自己上传了一个,修复了部分bug并添加了命名空间,里面也有工行所有的sdk文件,我在php7(thinkphp框架)和php8(webman框架)下使用暂时没有发现问题
安装命令:
composer require jian1098/icbc-sdk
如果报错Internal Server Error {"error":"Class \"jian1098\\icbc\\DefaultIcbcClient\" not found"
,那么在composer.json手动加载一次,具体步骤如下:
1.在autoload
节点增加代码
"classmap": [
"vendor/jian1098/icbc-sdk/src"
]
2.在命令行执行composer dump-autoload -o
即可
这里另外提供其他大佬上传的扩展包,但不保证能用(好像有部分文件会报有默认值的参数必须放在最后的错误):
1.https://github.com/johnorcc/icbcPayLib
(这个库使用rsa密钥对的时候好像必须要有类似-----BEGIN PUBLIC KEY-----
开头结尾并且64个字符换一行的格式,否则openssl_verify
会报错)
2.https://github.com/fatryst/icbc
开通权限
工行业务员开好平台账户之后接着要做的就是让他给你开通需要的接口权限,每个接口基本上都要单独开通,否则就会出现下面这个没有权限的报错,需要的接口都可以在开放平台的接口列表中找到
创建客户端
工行提供的sdk里面包含两种客户端:DefaultIcbcClient
为api接口客户端,这种是通过json传输的,需要自己写界面;UiIcbcClient
是带h5界面的客户端,不需要自己写界面,打开直接会跳转到工行的h5界面,这种适用于h5的项目。
<?php
namespace app\api\controller;
use app\common\controller\Api;
use IcbcConstants;
use think\Request;
use DefaultIcbcClient;
use UiIcbcClient;
/**
* 工行聚富通api
*/
class Icbc extends Api
{
protected $noNeedLogin = ['*'];
protected $config; // 工行配置
protected $apiClient; // api客户端
protected $uiClient; // h5客户端
/**
* 构造方法
*/
public function __construct(Request $request = null)
{
parent::__construct($request);
// 初始化工行配置
$this->config = [
// 工行申请的app_id
'appId' => 'your appid',
// 商户号(档案编号,特约商户12位,特约部门15位),暂时用不到
'merId' => 'your merid',
// 工行api地址
'url' => 'https://gw.open.icbc.com.cn', //正式环境url
//AES密钥
'AesKey' => 'your aeskey',
// APP应用私钥,需要工行工作人员先在工行后台【用户中心-我的应用-密钥信息】配置对应的应用公钥(不需要以'------'的密钥开头和结尾也不用换行)
'privateKey' => 'your privateKey',
// 生产环境网关公钥,问工行工作人员获取(不需要以'------'的密钥开头和结尾也不用换行)
'icbcPulicKey' => 'your icbcPulicKey',
];
//由于sdk没有使用命名空间,所以需要手动引入
Loader::import('icbc-api-sdk-cop-php.DefaultIcbcClient', VENDOR_PATH, '.php');
Loader::import('icbc-api-sdk-cop-php.UiIcbcClient', VENDOR_PATH, '.php');
//创建api客户端
$this->apiClient = new \DefaultIcbcClient(
$this->config['appId'], //app_id
$this->config['privateKey'], //应用私钥
IcbcConstants::$SIGN_TYPE_RSA2, //签名类型
'',
'',
$this->config['icbcPulicKey'], //工行网关公钥
'',
'',
'',
'');
//创建h5客户端
$this->uiClient = new \UiIcbcClient(
$this->config['appId'], //app_id
$this->config['privateKey'], //应用私钥
IcbcConstants::$SIGN_TYPE_RSA2, //签名类型
'',
'',
'',
'',
'',
'',
'');
}
}
注册子商户
在调用支付功能前必须要有一个商家收款账户,也就是商家必须用证件注册子商户,然后用商户号收款。对于同一个工行appid,可以在该appid下注册很多个子商户,商户注册子商户之后可以获得一个商户号,这个商户号是用来收款用的。不同appid下注册的子商户不通用,如果商户在不同平台开店,平台的appid不同,那就需要在每个平台都要注册子商户。
下面分别用h5和api方式调用工行子商户注册功能:
<?php
namespace app\api\controller;
use app\common\controller\Api;
use IcbcConstants;
use think\Loader;
use think\Request;
/**
* 工行聚富通api
*/
class Icbc extends Api
{
protected $noNeedLogin = ['*'];
protected $config; // 工行配置
protected $apiClient; // api客户端
protected $uiClient; // h5客户端
/**
* 构造方法
*/
public function __construct(Request $request = null)
{
parent::__construct($request);
// 初始化工行配置
$this->config = [
// 工行申请的app_id
'appId' => 'your appid',
// 商户号(档案编号,特约商户12位,特约部门15位),暂时用不到
'merId' => 'your merid',
// 工行api地址
'url' => 'https://gw.open.icbc.com.cn', //正式环境url
//AES密钥
'AesKey' => 'your aeskey',
// APP应用私钥,需要工行工作人员先在工行后台【用户中心-我的应用-密钥信息】配置对应的应用公钥
'privateKey' => 'your privateKey',
// 生产环境网关公钥,问工行工作人员获取
'icbcPulicKey' => 'your icbcPulicKey',
];
//由于sdk没有使用命名空间,所以需要手动引入
Loader::import('icbc-api-sdk-cop-php.DefaultIcbcClient', VENDOR_PATH, '.php');
Loader::import('icbc-api-sdk-cop-php.UiIcbcClient', VENDOR_PATH, '.php');
//创建api客户端
$this->apiClient = new \DefaultIcbcClient(
$this->config['appId'], //app_id
$this->config['privateKey'], //应用私钥
IcbcConstants::$SIGN_TYPE_RSA2, //签名类型
'',
'',
$this->config['icbcPulicKey'], //工行网关公钥
'',
'',
'',
'');
//创建h5客户端
$this->uiClient = new \UiIcbcClient(
$this