Files
yusheng-php/extend/Yzh/YunPay.php

382 lines
21 KiB
PHP
Raw Normal View History

2025-08-07 20:21:47 +08:00
<?php
namespace Yzh;
use think\Log;
use Yzh\Config; // 确保该类文件已被正确引入或自动加载
use Yzh\BaseClient;
use Yzh\Model\Apiusersign\ApiUserSignContractRequest;
use Yzh\Model\Apiusersign\ApiUserSignReleaseRequest;
use Yzh\Model\Apiusersign\ApiUserSignRequest;
use Yzh\Model\Apiusersign\GetApiUserSignStatusRequest;
use Yzh\Model\Payment\CreateAlipayOrderRequest;
use Yzh\Model\Payment\CreateBankpayOrderRequest;
use Yzh\Model\Payment\CreateWxpayOrderRequest;
use Yzh\Model\Notify\NotifyRequest;
use Yzh\NotifyClient;
class YunPay
{
public $order_id;
public $real_name;
public $id_card;
public $card_no;
public $order_amount;
public $notify_url = 'http://chat.qxmier.com/api/Payment/yun_callback';
public $phone = '';
public $config;
public $remark = '';
public $sys_config;
public function __construct($order_id="", $real_name="", $id_card="", $card_no="", $order_amount="", $phone="")
{
//读取配置
$this->sys_config = new SysConfig();
$this->order_id = $order_id;
$this->real_name = $real_name;
$this->id_card = $id_card;
$this->card_no = $card_no;
$this->order_amount = $order_amount;
$this->phone = $phone;
//读取配置
$this->config = Config::newFromArray(array(
'app_dealer_id' => $this->sys_config->dealer_id,
'app_broker_id' => $this->sys_config->broker_id,
'app_key' => $this->sys_config->app_key,
'app_des3_key' => $this->sys_config->des3_key,
'app_private_key' => $this->sys_config->private_key,
'yzh_public_key' => $this->sys_config->public_key,
'sign_type' => $this->sys_config->sign_type
));
}
public function alipay(){
try {
$this->paymentClient = new PaymentClient($this->config);
$this->paymentClient->setEnv(PaymentClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
$request = new CreateAlipayOrderRequest(array(
'order_id' => $this->order_id, // 平台企业订单号,由平台企业保持唯⼀性 ,至多支持 64 个英⽂字符
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
'real_name' => $this->real_name, // 姓名
'card_no' => $this->card_no, // 收款⼈⽀付宝账户
'id_card' => $this->id_card, // 身份证号码(必填,报税时使用)
'phone_no' => $this->phone, // ⽤户⼿机号
'pay' => $this->order_amount, // 订单⾦额(参数类型是 string单位为元支持两位小数必填
'pay_remark' => $this->remark, // 订单备注(选填,至多支持 40 个字符且不支持特殊字符,⼀个汉字占 2 个字符,不支持的特殊字符为 ' " & | @% ( ) - : # + / < > ¥ \ ,
'check_name' => 'Check', // 校验⽀付宝账户姓名(固定值 Check
'notify_url' => $this->notify_url, // 回调地址(选填,长度不超过 200 个字符)
'project_id' => '' // 项目ID该字段由云账户分配当接口指定项目时会将订单关联指定项目
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->paymentClient->createAlipayOrder($request);
if ($response->isSuccess()) {
// TODO 操作成功,支付结果未知,等待异步通知或订单查询接口获取订单状态
return ['code' => 1, 'msg' => '接单成功', 'data' => null];
} elseif ($response->getCode() == '2002') {
// TODO 幂等性校验,订单号已存在,具体订单结果需等待异步通知,或主动调用订单查询接口获取
return ['code' => 0, 'msg' => '订单已存在', 'data' => null];
} else {
// TODO 失败返回,根据返回的 message 处理订单请求,切记若需重试请求,请使用原订单号重试
return ['code' => $response->getCode(), 'msg' => $response->getMessage(). ' request-id:' . $response->getRequestID(), 'data' => null];
}
}
public function Wxpay($wx_openid)
{
try {
$this->paymentClient = new PaymentClient($this->config);
$this->paymentClient->setEnv(PaymentClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
$request = new CreateWxpayOrderRequest(array(
'order_id' => $this->order_id, // 平台企业订单号,由平台企业保持唯⼀性,至多支持 64 个英⽂字符
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
'real_name' => $this->real_name, // 姓名
'openid' => $wx_openid, // 平台企业 AppID 下⽤户的 openid
'id_card' => $this->card_no, // 身份证号码(必填,报税时使用)
'phone_no' => $this->phone, // ⽤户⼿机号
'pay' => $this->order_amount, // 订单⾦额(参数类型是 string单位为元支持两位小数必填
'pay_remark' => $this->remark, // 订单备注(选填,至多支持 32 个字符且不支持特殊字符,⼀个汉字占 2 个字符,不支持的特殊字符为 ' " & | @% ( ) - : # + / < > ¥ \ ,
'wx_app_id' => '', // 平台企业微信 AppID选填最⼤⻓度为 200若平台企业在云账户绑定了多个 AppID则此处需指定 AppID
'notify_url' => $this->notify_url, // 回调地址(选填,长度不超过 200 个字符)
'wxpay_mode' => 'transfer', // 微信支付模式必填固定值transfer
'project_id' => '' // 项目 ID该字段由云账户分配当接口指定项目时会将订单关联指定项目
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->paymentClient->createWxpayOrder($request);
if ($response->isSuccess()) {
// TODO 操作成功,支付结果未知,等待异步通知或订单查询接口获取订单状态
return ['code' => 1, 'msg' => '接单成功', 'data' => null];
} elseif ($response->getCode() == '2002') {
// TODO 幂等性校验,订单号已存在,具体订单结果需等待异步通知,或主动调用订单查询接口获取
return ['code' => 0, 'msg' => '订单已存在', 'data' => null];
} else {
// TODO 失败返回,根据返回的 message 处理订单请求,切记若需重试请求,请使用原订单号重试
return ['code' => $response->getCode(), 'msg' => $response->getMessage(). ' request-id:' . $response->getRequestID(), 'data' => null];
}
}
public function bank()
{
try {
$this->paymentClient = new PaymentClient($this->config);
$this->paymentClient->setEnv(PaymentClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
// 银行卡实时支付
$request = new CreateBankpayOrderRequest(array(
'order_id' => $this->order_id,
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
'real_name' => $this->real_name,
'card_no' => $this->id_card,
'id_card' => $this->card_no,
'phone_no' => $this->phone,
'pay' => $this->order_amount,
'pay_remark' => $this->remark,
'notify_url' => $this->notify_url,
'project_id' => ''
));
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->paymentClient->createBankpayOrder($request);
if ($response->isSuccess()) {
// TODO 操作成功,支付结果未知,等待异步通知或订单查询接口获取订单状态
return ['code' => 1, 'msg' => '接单成功', 'data' => null];
} elseif ($response->getCode() == '2002') {
// TODO 幂等性校验,订单号已存在,具体订单结果需等待异步通知,或主动调用订单查询接口获取;
return ['code' => 0, 'msg' => '订单已存在', 'data' => null];
} else {
// TODO 失败返回,根据返回的 message 处理订单请求,切记若需重试请求,请使用原订单号重试
return ['code' => $response->getCode(), 'msg' => $response->getMessage(). ' request-id:' . $response->getRequestID(), 'data' => null];
}
}
/*
* 订单状态查询
*/
public function queryOrder($type){
try {
$this->paymentClient = new PaymentClient($this->config);
$this->paymentClient->setEnv(PaymentClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
if($type == 1){
$channel = '微信';
}elseif($type == 2){
$channel = '支付宝';
}else{
$channel = '银行卡';
}
// 查询单笔订单信息
$request = new \Yzh\Model\Payment\GetOrderRequest(array(
'order_id' => $this->order_id, // 平台企业订单号,由平台企业保持唯⼀性
'channel' => $channel, // 支付路径名,银⾏卡,⽀付宝,微信(选填,不填默认为银⾏卡订单查询,注意 value 值为中文字符)
'data_type' => '', // 如果为 encryption则对返回的 data 进行加密
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->paymentClient->getOrder($request);
if ($response->isSuccess()) {
// TODO 订单查询操作成功,根据订单状态 status 判断订单状态,做业务订单的处理
if($response->getData()->getStatusDetail() == 0){
return ['code' => 1, 'msg' => "订单状态:" . $response->getData()->getStatusMessage(), 'data' => [
'code' => $response->getData()->getStatusDetail(),
'msg' => $response->getData()->getStatusMessage(),
]];
}else{
return ['code' => 1, 'msg' => "订单状态:" . $response->getData()->getStatusDetailMessage(), 'data' => [
'code' => $response->getData()->getStatusDetail(),
'msg' => $response->getData()->getStatusDetailMessage(),
]];
}
} else if ($response->getCode() == '2018') {
// TODO 订单不存在,检查一下 channel 是否传递正确,若正确,则可以使用原 order_id 再次下单
return ['code' => 0, 'msg' => "订单不存在", 'data' => null];
} else {
// TODO 失败返回,其他 code 应当做异常情况,订单状态当“未知”处理,可稍后重试直至获取到 code=0000 或 2018或者是联系云账户进行人工查询
return ['code' => $response->getCode(), 'msg' => $response->getMessage() . ' request-id:' . $response->getRequestID(), 'data' => null];
}
}
/*
* 回调接口处理
*/
public function yun_callback($data,$mess,$timestamp,$sign){
$notifyClient = new NotifyClient($this->config);
// 异步回调参数
$notifyReq = new NotifyRequest ($data, $mess, $timestamp, $sign) ;// 发起验签解密
try {
$result = $notifyClient->verifyAndDecrypt($notifyReq) ;
Log::record("云账户回调信息".json_encode($result),"info");
if ($result) {
// 验签通过、解密成功
return ['code' => 1, 'msg' => "验签通过、解密成功:", 'data' => $result];
}else{
return ['code' => 0, 'msg' => "验签失败", 'data' => null];
}
}
catch(Exception $e){
// 发生异常
return ['code' => 0, 'msg' => $e->getMessage (), 'data' => null];
}
}
/*
* 获取协议预览 URL
*/
public function getAgreementPreviewUrl(){
try {
$this->ApiUserSignServiceClient = new ApiUserSignServiceClient($this->config);
$this->ApiUserSignServiceClient->setEnv(ApiUserSignServiceClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
$request = new ApiUserSignContractRequest(array(
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->ApiUserSignServiceClient->apiUserSignContract($request);
if ($response->isSuccess()) {
// TODO 获取协议预览 URL 操作成功
return ['code' => 1, 'msg' => "获取协议预览 URL 操作成功", 'data' => [
'url' => $response->getData()->getUrl(),
'title' => $response->getData()->getTitle(),
]];
}else{
return ['code' => 0, 'msg' => "获取协议预览 URL 操作失败", 'data' => null];
}
}
/*
* 用户签约
*/
public function apiUserSign($real_name,$id_card){
try {
$this->ApiUserSignServiceClient = new ApiUserSignServiceClient($this->config);
$this->ApiUserSignServiceClient->setEnv(ApiUserSignServiceClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
// 配置请求参数
$request = new ApiUserSignRequest(array(
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
"real_name" => $real_name,
"id_card" => $id_card,
"card_type" => "idcard",
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->ApiUserSignServiceClient->apiUserSign($request);
if ($response->isSuccess()) {
// TODO 用户签约操作成功
return ['code' => 1, 'msg' => "用户签约操作成功", 'data' => ['request_id' => $request_id]];
}else{
return ['code' => 0, 'msg' => "用户签约操作失败:".$response->getMessage(), 'data' => null];
}
}
/**
* 获取用户签约状态
*/
public function getApiUserSignStatus($real_name,$id_card){
try {
$this->ApiUserSignServiceClient = new ApiUserSignServiceClient($this->config);
$this->ApiUserSignServiceClient->setEnv(ApiUserSignServiceClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
// 配置请求参数
$request = new GetApiUserSignStatusRequest(array(
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
"real_name" => $real_name,
"id_card" => $id_card
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->ApiUserSignServiceClient->getApiUserSignStatus($request);
if ($response->isSuccess()) {
// TODO 用户签约操作成功
return ['code' => 1, 'msg' => "用户签约状态查询", 'data' =>
[
'sign_status' => $response->getData()->getStatus(),
'sign_time' => $response->getData()->getSignedAt(),
]];
}else{
return ['code' => 0, 'msg' => "用户签约状态查询:".$response->getMessage(), 'data' => null];
}
}
/**
* 用户解约
*/
public function unSignYunAccount($real_name,$id_card){
try {
$this->ApiUserSignServiceClient = new ApiUserSignServiceClient($this->config);
$this->ApiUserSignServiceClient->setEnv(ApiUserSignServiceClient::ENV_PROD);
} catch (\Exception $e) {
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
// 配置请求参数
$request = new ApiUserSignReleaseRequest(array(
'dealer_id' => $this->sys_config->dealer_id, // 平台企业 ID
'broker_id' => $this->sys_config->broker_id, // 综合服务主体 ID
"real_name" => $real_name,
"id_card" => $id_card,
"card_type" => "idcard",
));
/*
* request-id请求 ID请求的唯一标识
* 建议平台企业自定义 request-id并记录在日志中便于问题发现及排查
* 如未自定义 request-id将使用 SDK 中的 random 方法自动生成。注意random 方法生成的 request-id 不能保证全局唯一,推荐自定义 request-id
*/
$request_id = "requestId".$this->order_id.time().rand(100000,999999).UniqId();
$request->setRequestID($request_id);
$response = $this->ApiUserSignServiceClient->apiUserSignRelease($request);
if ($response->isSuccess()) {
// TODO 用户签约操作成功
return ['code' => 1, 'msg' => "用户解约操作成功", 'data' => ['request_id' => $request_id]];
}else{
return ['code' => 0, 'msg' => "用户解约操作失败:".$response->getMessage(), 'data' => null];
}
}
}