160 lines
6.1 KiB
PHP
160 lines
6.1 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
use Illuminate\Auth\Events\Login;
|
||
use Illuminate\Support\Facades\Log;
|
||
use WeChatPay\Builder;
|
||
use WeChatPay\BuilderChainable;
|
||
use WeChatPay\Crypto\Rsa;
|
||
|
||
class WechatPayService
|
||
{
|
||
/**
|
||
* 初始化一个APIv3客户端
|
||
* @return void
|
||
*/
|
||
private function newClient(): BuilderChainable
|
||
{
|
||
// 商户号
|
||
$merchantId = config("wechatpay.payment.mch_id");
|
||
|
||
// 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
|
||
$merchantPrivateKeyFilePath = 'file://' . config("wechatpay.payment.cert_key_path");
|
||
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
|
||
|
||
// 「商户API证书」的「证书序列号」
|
||
$merchantCertificateSerial = config("wechatpay.payment.serial");
|
||
|
||
// 从本地文件中加载「微信支付平台证书」,可由内置CLI工具下载到,用来验证微信支付应答的签名
|
||
$platformCertificateFilePath = 'file://' . config("wechatpay.payment.platform_cert_path");
|
||
$onePlatformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||
|
||
// 「微信支付平台证书」的「平台证书序列号」
|
||
// 可以从「微信支付平台证书」文件解析,也可以在 商户平台 -> 账户中心 -> API安全 查询到
|
||
$platformCertificateSerial = config("wechatpay.payment.platform_cert_serial");
|
||
|
||
// // 从本地文件中加载「微信支付公钥」,用来验证微信支付应答的签名
|
||
// $platformPublicKeyFilePath = 'file://' . config("wechatpay.payment.public_key_path");
|
||
// $twoPlatformPublicKeyInstance = Rsa::from($platformPublicKeyFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||
|
||
// // 「微信支付公钥」的「微信支付公钥ID」
|
||
// // 需要在 商户平台 -> 账户中心 -> API安全 查询
|
||
// $platformPublicKeyId = config("wechatpay.payment.public_key_id");
|
||
|
||
// 构造一个 APIv3 客户端实例
|
||
$instance = Builder::factory([
|
||
'mchid' => $merchantId,
|
||
'serial' => $merchantCertificateSerial,
|
||
'privateKey' => $merchantPrivateKeyInstance,
|
||
'certs' => [
|
||
$platformCertificateSerial => $onePlatformPublicKeyInstance,
|
||
// $platformPublicKeyId => $twoPlatformPublicKeyInstance,
|
||
],
|
||
"secret" => config("wechatpay.payment.api3_key")
|
||
]);
|
||
return $instance;
|
||
}
|
||
|
||
/**
|
||
* 商家转账
|
||
* @return void
|
||
*/
|
||
public function mchTransfer(string $trade_no, string $scene_id, string $openid, int $amount, string $remark, array $transfer_scene_report_infos = []): array
|
||
{
|
||
// 发送请求
|
||
if (empty(count($transfer_scene_report_infos))) {
|
||
$transfer_scene_report_infos = [
|
||
[
|
||
'info_type' => '岗位类型', // 固定值
|
||
'info_content' => '商家/商户', // 示例值
|
||
],
|
||
[
|
||
'info_type' => '报酬说明', // 固定值
|
||
'info_content' => '商家/商户提现', // 示例值
|
||
],
|
||
];
|
||
}
|
||
try {
|
||
$appid = config("wechat.official_account.default.app_id");
|
||
$data = [
|
||
"appid" => $appid,
|
||
"out_bill_no" => $trade_no,
|
||
"transfer_scene_id" => (string) $scene_id,
|
||
"openid" => $openid,
|
||
"transfer_amount" => $amount,
|
||
"transfer_remark" => $remark,
|
||
"transfer_scene_report_infos" => $transfer_scene_report_infos
|
||
];
|
||
Log::info("转账数据", $data);
|
||
$instance = $this->newClient();
|
||
$resp = $instance->chain('v3/fund-app/mch-transfer/transfer-bills')->post([
|
||
"json" => $data
|
||
]);
|
||
$res = json_decode($resp->getBody(), true);
|
||
dd($res);
|
||
} catch (\Exception $e) {
|
||
// 进行异常捕获并进行错误判断处理
|
||
Log::info($e->getMessage());
|
||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||
$r = $e->getResponse();
|
||
$res = json_decode($r->getBody());
|
||
return ["code" => 1, "err_msg" => $r->getBody()];
|
||
}
|
||
|
||
return ["code" => 1, "err_msg" => $e->getMessage()];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 商家批量转账到零钱
|
||
*/
|
||
|
||
public function transferBatches(string $trade_no, string $trade_no2, string $openid, int $amount, string $remark): array
|
||
{
|
||
try {
|
||
$appid = config("wechat.official_account.default.app_id");
|
||
$data = [
|
||
"appid" => $appid,
|
||
"out_bill_no" => $trade_no,
|
||
"batch_name" => $remark,
|
||
"batch_remark" => $remark,
|
||
"total_amount" => $amount,
|
||
"total_num" => 1,
|
||
"transfer_detail_list" => [
|
||
"out_detail_no" => $trade_no2,
|
||
"transfer_amount" => $amount,
|
||
"transfer_remark" => $remark,
|
||
"openid" => $openid,
|
||
]
|
||
];
|
||
Log::info("转账到零钱数据", $data);
|
||
$instance = $this->newClient();
|
||
$resp = $instance->chain('v3/transfer/batches')->post([
|
||
"json" => $data
|
||
]);
|
||
$res = json_decode($resp->getBody(), true);
|
||
dd($res);
|
||
} catch (\Exception $e) {
|
||
// 进行异常捕获并进行错误判断处理
|
||
Log::info($e->getMessage());
|
||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||
$r = $e->getResponse();
|
||
$res = json_decode($r->getBody());
|
||
return ["code" => 1, "err_msg" => $r->getBody()];
|
||
}
|
||
|
||
return ["code" => 1, "err_msg" => $e->getMessage()];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 转账银行卡
|
||
* @return void
|
||
*/
|
||
public function bankTransfer()
|
||
{
|
||
|
||
}
|
||
}
|