当前位置: 首页 > 工具软件 > PHP Open Biz > 使用案例 >

php版工行聚合支付和e支付

元昊苍
2023-12-01

以下是自己写的调用支付和退款和查询订单

<?php

namespace Org\IcbcPhp;

use Exception;

/**
 * Class ICBCPay
 * 工银支付
 */
class ICBCPay
{

    private $client;

    private $payType;

    /**
     * ICBCPay constructor.
     * @param string $payType 9 微信 10 支付宝 11 e支付
     */
    public function __construct($payType)
    {
        $this->payType = $payType . "";
        if ($payType == "9" || $payType == "10" || !$payType) {
            $this->client = new DefaultIcbcClient(C("icbc_app_id"), C("icbc_private_key"), C("icbc_sign_type"), C("icbc_charset"), C("icbc_format"), C("icbc_gateway_public_key"), C("icbc_encryptKey"), C("icbc_encryptType"), "", "");
        } elseif ($payType == "11") {
            $this->client = new UiIcbcClient(C("icbc_app_id"), C("icbc_private_key"), C("icbc_sign_type"), C("icbc_charset"), C("icbc_format"), C("icbc_gateway_public_key"), C("icbc_encryptKey"), C("icbc_encryptType"), "", "");
        }
    }

    /**
     * app 支付宝和微信下单
     * 张志强
     * 2021-01-12
     * @param string $subMerchantId 商户号
     * @param string $mer_prtcl_no 协议编号
     * @param string $orderId 订单号
     * @param string $money 金额
     * @param string $decive 设备号
     * @param string $attach 附加字段
     * @param string $clientIp 设备ip
     * @param string $notifyUrl 回调地址
     * @return false|string
     * @throws Exception
     */
    public function appPay($subMerchantId, $mer_prtcl_no, $orderId, $money, $decive, $attach, $clientIp, $notifyUrl)
    {
        if ($this->payType == 11) {
            throw new Exception("请使用e支付的接口");
        }
        $data = [
            'serviceUrl' => 'https://gw.open.icbc.com.cn/api/cardbusiness/aggregatepay/b2c/online/consumepurchase/V1',
            'biz_content' => get_object_vars(new ICBCPayBizContentParameter($subMerchantId, $mer_prtcl_no, $orderId . "", $this->payType, $decive, $money . "", $attach, $clientIp, $notifyUrl)),
            'extraParams' => [],
            'method' => "POST",
            'isNeedEncrypt' => true
        ];

        return $this->client->execute($data, $orderId, "");
    }

    /**
     * e支付 h5
     * 张志强
     * 2021-01-12
     * @param string $subMerchantId 商户号
     * @param string $mer_prtcl_no 协议编号
     * @param string $orderId string     订单号
     * @param string $money string      金额
     * @param string $attach string     附加字段
     * @param boolean $isInApp bool 是否嵌入app内
     * @param string $notifyUrl 回调地址
     * @param string $returnUrl 支付完跳转地址
     * @return string
     * @throws Exception
     */
    public function ePay($subMerchantId, $mer_prtcl_no, $orderId, $money, $attach, $isInApp, $notifyUrl, $returnUrl)
    {
        if ($this->payType != 11) {
            throw new Exception("请使用聚合支付的接口");
        }
        $data = [
            'serviceUrl' => 'https://gw.open.icbc.com.cn/ui/cardbusiness/epayh5/ui/consumption/V1',
            'biz_content' => get_object_vars(new ICBCEPayBizContentParameter($subMerchantId, $mer_prtcl_no, $orderId . "", $money . "", $attach, $isInApp, $notifyUrl, $returnUrl)),
            'extraParams' => [],
            'method' => "POST",
            'isNeedEncrypt' => true
        ];

        return $this->client->buildPostForm($data, $orderId, "");
    }

    /**
     * 退款
     * 张志强
     * 2021-01-12
     * @param string $subMerchantId 商户编号
     * @param string $refundId 自己生成的唯一退款id
     * @param string $orderId 订单号
     * @param string $money 金额
     * @return false|string
     * @throws Exception
     */
    public function refund($subMerchantId, $refundId, $orderId, $money)
    {
        // 退款
        $data = [
            'serviceUrl' => 'https://gw.open.icbc.com.cn/api/cardbusiness/aggregatepay/b2c/online/merrefund/V1',
            'biz_content' => get_object_vars(new ICBCRefundBizContentParameter($subMerchantId, $refundId . "", $orderId . "", $money . "")),
            'extraParams' => [],
            'method' => "POST",
            'isNeedEncrypt' => true
        ];
        return $this->client->execute($data, $orderId, "");
    }

    // 查询订单

    /**
     * @param $subMerchantId
     * @param $serial_number
     * @return false|string
     * @throws Exception
     */
    public function selectIcbcOrder($subMerchantId, $serial_number)
    {
        $data = [
            'serviceUrl' => 'https://gw.open.icbc.com.cn/api/cardbusiness/aggregatepay/b2c/online/orderqry/V1',
            'biz_content' => [
                'mer_id' => $subMerchantId,
                'out_trade_no' => $serial_number,
                'deal_flag' => "0",
                'icbc_appid' => C('icbc_app_id')
            ],
            'extraParams' => [],
            'method' => "POST",
            'isNeedEncrypt' => true
        ];

        return $this->client->execute($data, microtime(), "");
    }
}

支付回调

/**
     * 工银支付回调
     * @throws Exception
     */
    public function icbcNotify() {
        $file_pointer = fopen(APP_PATH."/Lib/Action".__GROUP__."/aa.txt","a+");
        fwrite($file_pointer,"回调开始");
        try {
            // 获取参数
            $responseStr = urldecode(file_get_contents("php://input"));
            if (!$responseStr) {
                throw new Exception("【".date("Y-m-d H:i:s")."】  参数不能为空\r\n");
            }
            $response = explode("&",$responseStr);
            $responseArr = [];
            $sign = "";
            foreach ($response as $k => $v) {
                if (strstr($v,"=",true) == 'sign') {
                    $sign = substr(strstr($v,"=",false),1);
                } else {
                    $responseArr[strstr($v,"=",true)] = substr(strstr($v,"=",false),1);
                }
            }

            // 生成待签名字符串
            $path = parse_url('域名' +'接口名', PHP_URL_PATH);
            $respBizContentStr = WebUtils::buildOrderedSignStr($path,$responseArr);

            // 验证签名1
            $passed = IcbcSignature::verify($respBizContentStr, $responseArr['sign_type'], C("icbc_gateway_public_key"), $responseArr['charset'], $sign,'');
            if (!$passed) {
                $responseArr = json_encode($responseArr);
                throw new Exception("【".date("Y-m-d H:i:s")."】  icbc sign verify not passed!\r\n订单信息为【{$responseArr}】签名为【{$sign}】\r\n");
            }

            // 返回业务参数
            $bizContent = json_decode($responseArr['biz_content'],true);

            $merOrderId = $bizContent['out_trade_no'];
            $notify_return_code = $bizContent['return_code'];

            // 验证返回消息码是否正确
            if ($notify_return_code !== "0") {
                return $this->response("-1","error");
            }

            // 修改unipay_log
            $result = M('unionpay_log')->data(['is_valid' => 2])->where(['serial_number'=>$merOrderId])->save();
            if ($result === false) {
                throw new Exception("【".date("Y-m-d H:i:s")."】  修改unipay_log失败!\r\n订单信息为【{$responseArr}】签名为【{$sign}】\r\n");
            }

        	// 自己的业务逻辑
			//return $this->response("0","success");成功响应
			//return $this->response("-1","error");失败响应

        } catch (Exception $exception) {
            fwrite($file_pointer,$exception->getMessage());
            return $this->response("-1","error");
        }
    }

    /**
     * 工行回调应答
     * 张志强
     * 2021-07-15
     */
    private function response($return_code,$return_msg) {
        // 应答
        $respBizContent = array(
            'return_code' => $return_code,
            'return_msg' => $return_msg,
            'msg_id' => microtime()
        );

        $answer['response_biz_content'] = json_encode($respBizContent);
        $answer['sign_type'] = C('icbc_sign_type');
        $answer['sign'] = IcbcSignature::sign(substr(json_encode($answer),1),C("icbc_sign_type"),C("icbc_private_key"),C("icbc_charset"),'');

        return json_encode($answer);
    }

强调:
在支付回调签名验证的时候的path不要自己手写,会发生验签不通过,切记要用

 $path = parse_url('域名' +'接口名', PHP_URL_PATH);

php工行SDK下载地址

 类似资料: