mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
189 lines
5.2 KiB
PHP
189 lines
5.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace addons\shopro\library\ccblife;
|
||
|
|
|
||
|
|
use think\Exception;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 建行支付服务类
|
||
|
|
*
|
||
|
|
* 功能:
|
||
|
|
* - 生成建行支付串
|
||
|
|
* - 处理支付回调
|
||
|
|
* - 验证支付结果
|
||
|
|
*
|
||
|
|
* @author Billy
|
||
|
|
* @date 2025-01-16
|
||
|
|
*/
|
||
|
|
class CcbPaymentService
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 配置信息
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
private $config;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 加密实例
|
||
|
|
* @var CcbEncryption
|
||
|
|
*/
|
||
|
|
private $encryption;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 构造函数
|
||
|
|
*
|
||
|
|
* @param array $config 配置数组
|
||
|
|
*/
|
||
|
|
public function __construct($config = [])
|
||
|
|
{
|
||
|
|
if (empty($config)) {
|
||
|
|
$config = config('ccblife');
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->config = $config;
|
||
|
|
$this->encryption = new CcbEncryption($config);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 生成支付串
|
||
|
|
*
|
||
|
|
* @param array $order 订单数据
|
||
|
|
* @return array 返回结果 ['success' => bool, 'payment_string' => string, 'pay_flow_id' => string]
|
||
|
|
*/
|
||
|
|
public function generatePaymentString($order)
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
// 1. 生成支付流水号
|
||
|
|
$payFlowId = $this->encryption->generatePayFlowId();
|
||
|
|
|
||
|
|
// 2. 构造支付参数
|
||
|
|
$params = $this->buildPaymentParams($order, $payFlowId);
|
||
|
|
|
||
|
|
// 3. 生成支付串签名
|
||
|
|
$mac = $this->encryption->generatePaymentSign($params);
|
||
|
|
|
||
|
|
// 4. 加密商户公钥
|
||
|
|
$encPub = $this->encryption->encryptMerchantPublicKey();
|
||
|
|
|
||
|
|
// 5. 添加签名和加密字段
|
||
|
|
$params['MAC'] = $mac;
|
||
|
|
$params['PLATFORMID'] = $this->config['service_id'];
|
||
|
|
$params['ENCPUB'] = $encPub;
|
||
|
|
|
||
|
|
// 6. 生成支付串
|
||
|
|
$paymentString = http_build_query($params);
|
||
|
|
|
||
|
|
return [
|
||
|
|
'success' => true,
|
||
|
|
'payment_string' => $paymentString,
|
||
|
|
'pay_flow_id' => $payFlowId,
|
||
|
|
];
|
||
|
|
|
||
|
|
} catch (Exception $e) {
|
||
|
|
return [
|
||
|
|
'success' => false,
|
||
|
|
'error' => $e->getMessage(),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 处理支付回调
|
||
|
|
*
|
||
|
|
* @param array $callbackData 回调数据
|
||
|
|
* @return array 返回结果
|
||
|
|
*/
|
||
|
|
public function handleCallback($callbackData)
|
||
|
|
{
|
||
|
|
// 支付回调处理逻辑
|
||
|
|
// 建行支付成功后会通过notify_url回调
|
||
|
|
|
||
|
|
return [
|
||
|
|
'success' => true,
|
||
|
|
'trans_id' => $callbackData['trans_id'] ?? '',
|
||
|
|
'order_id' => $callbackData['order_id'] ?? '',
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 验证支付结果
|
||
|
|
*
|
||
|
|
* @param string $orderId 订单ID
|
||
|
|
* @return bool 是否支付成功
|
||
|
|
*/
|
||
|
|
public function verifyPayment($orderId)
|
||
|
|
{
|
||
|
|
// 通过订单查询接口验证支付结果
|
||
|
|
$orderService = new CcbOrderService($this->config);
|
||
|
|
$result = $orderService->queryOrder($orderId);
|
||
|
|
|
||
|
|
if ($result['success']) {
|
||
|
|
$orderStatus = $result['data']['CLD_BODY']['ORDER_STATUS'] ?? '0';
|
||
|
|
return $orderStatus === '1'; // 1-已支付
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 构造支付参数
|
||
|
|
*
|
||
|
|
* @param array $order 订单数据
|
||
|
|
* @param string $payFlowId 支付流水号
|
||
|
|
* @return array 支付参数
|
||
|
|
*/
|
||
|
|
private function buildPaymentParams($order, $payFlowId)
|
||
|
|
{
|
||
|
|
// 获取支付配置
|
||
|
|
$paymentConfig = $this->config['payment'] ?? [];
|
||
|
|
|
||
|
|
// 计算超时时间
|
||
|
|
$timeoutMinutes = $paymentConfig['timeout_minutes'] ?? 30;
|
||
|
|
$timeout = date('YmdHis', time() + $timeoutMinutes * 60);
|
||
|
|
|
||
|
|
return [
|
||
|
|
'MERCHANTID' => $this->config['merchant_id'],
|
||
|
|
'POSID' => $this->config['pos_id'],
|
||
|
|
'BRANCHID' => $this->config['branch_id'],
|
||
|
|
'ORDERID' => $payFlowId, // 支付流水号
|
||
|
|
'USER_ORDERID' => $order['order_sn'], // 商城订单号
|
||
|
|
'PAYMENT' => number_format($order['pay_amount'], 2, '.', ''),
|
||
|
|
'CURCODE' => $paymentConfig['currency_code'] ?? '01',
|
||
|
|
'TXCODE' => $paymentConfig['tx_code'] ?? '520100',
|
||
|
|
'REMARK1' => '',
|
||
|
|
'REMARK2' => $this->config['service_id'], // 重要: 必须填写服务方编号
|
||
|
|
'TYPE' => '1',
|
||
|
|
'GATEWAY' => '0',
|
||
|
|
'CLIENTIP' => $this->getClientIp(),
|
||
|
|
'THIRDAPPINFO' => $paymentConfig['third_app_info'] ?? 'comccbpay1234567890cloudmerchant',
|
||
|
|
'TIMEOUT' => $timeout,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取客户端IP
|
||
|
|
*
|
||
|
|
* @return string IP地址
|
||
|
|
*/
|
||
|
|
private function getClientIp()
|
||
|
|
{
|
||
|
|
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||
|
|
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||
|
|
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
|
||
|
|
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||
|
|
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||
|
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||
|
|
} else {
|
||
|
|
$ip = '127.0.0.1';
|
||
|
|
}
|
||
|
|
|
||
|
|
// 如果是多个IP,取第一个
|
||
|
|
if (strpos($ip, ',') !== false) {
|
||
|
|
$ips = explode(',', $ip);
|
||
|
|
$ip = trim($ips[0]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $ip;
|
||
|
|
}
|
||
|
|
}
|