345 lines
15 KiB
PHP
345 lines
15 KiB
PHP
<?php
|
||
|
||
namespace app\notify\controller;
|
||
|
||
use app\common\model\Requirement;
|
||
use app\common\model\RequirementOrder;
|
||
use app\common\service\Channel\wechat\WechatConstants;
|
||
use support\Request;
|
||
use think\Exception;
|
||
use WeChatPay\Crypto\AesGcm;
|
||
use WeChatPay\Crypto\Rsa;
|
||
use WeChatPay\Formatter;
|
||
|
||
class WechatPayNotifyController
|
||
{
|
||
/**
|
||
* @desc 需求订单支付回调
|
||
* @param Request $request
|
||
* @return void
|
||
*/
|
||
public function requirement_notify(Request $request)
|
||
{
|
||
try {
|
||
$post_data = $request->post();
|
||
$header = $request->header();
|
||
raw_log('wechat_pay/requirement_notify', ['post' => $post_data, 'header' => $header]);
|
||
|
||
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
|
||
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
|
||
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
|
||
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
|
||
|
||
$mch_id = getenv('MERCHANT_ID');
|
||
|
||
// 根据通知的平台证书序列号,查询本地平台证书文件,
|
||
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
|
||
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||
|
||
// 检查通知时间偏移量,允许5分钟之内的偏移
|
||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||
$verifiedStatus = Rsa::verify(
|
||
// 构造验签名串
|
||
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
|
||
$inWechatpaySignature,
|
||
$platformPublicKeyInstance
|
||
);
|
||
|
||
// 验签
|
||
if ($timeOffsetStatus && $verifiedStatus) {
|
||
// 使用PHP7的数据解构语法,从Array中解构并赋值变量
|
||
['resource' => [
|
||
'ciphertext' => $ciphertext,
|
||
'nonce' => $nonce,
|
||
'associated_data' => $aad
|
||
]] = $post_data;
|
||
// 加密文本消息解密
|
||
$inBodyResource = AesGcm::decrypt($ciphertext, getenv('API_V3'), $nonce, $aad);
|
||
// 把解密后的文本转换为PHP Array数组
|
||
$pay_result = json_decode($inBodyResource, true);
|
||
|
||
if ($pay_result['trade_state'] == 'SUCCESS') {
|
||
|
||
$order = RequirementOrder::where(['out_trade_no' => $pay_result['out_trade_no']])->findOrEmpty();
|
||
|
||
if ($order->isEmpty()) {
|
||
throw new Exception('未找到订单' . $pay_result['out_trade_no']);
|
||
}
|
||
if ($order->amount * 100 != $pay_result['amount']['total']) {
|
||
throw new Exception('订单金额不一致-' . $pay_result['out_trade_no']);
|
||
}
|
||
|
||
if ($order->pay_status == 0) {
|
||
$res = $order->save([
|
||
'pay_status' => 1,
|
||
'transaction_id' => $pay_result['transaction_id'],
|
||
'pay_time' => date('Y-m-d H:i:s', strtotime($pay_result['success_time'])),
|
||
]);
|
||
|
||
$requirement = Requirement::where(['id' => $order->requirement_id])->findOrEmpty();
|
||
$requirement->save([
|
||
'requirement_pay_order_status' => 1
|
||
]);
|
||
if ($requirement->deposit_pay_status == 1) {
|
||
//保证金已支付,进入服务中状态
|
||
$requirement->save([
|
||
'status' => 3
|
||
]);
|
||
}
|
||
|
||
if ($res) {
|
||
return json('success');
|
||
}
|
||
}
|
||
return json('success');
|
||
}
|
||
} else {
|
||
throw new Exception('验签失败');
|
||
}
|
||
|
||
} catch (Exception $e) {
|
||
var_dump($e->getMessage());
|
||
raw_log('wechat_pay/requirement_notify_error', ['exception' => $e->getMessage()]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @desc 需求退款
|
||
* @param Request $request
|
||
* @return \support\Response|void
|
||
*/
|
||
public function requirement_refund_notify(Request $request)
|
||
{
|
||
try {
|
||
$post_data = $request->post();
|
||
$header = $request->header();
|
||
|
||
$post_data = '{"id":"ce358553-a4ae-5ecd-bab0-c4a31292989d","create_time":"2024-07-04T17:40:35+08:00","resource_type":"encrypt-resource","event_type":"REFUND.SUCCESS","summary":"退款成功","resource":{"original_type":"refund","algorithm":"AEAD_AES_256_GCM","ciphertext":"uc/STAVhRAgsEn+Wcl7ZDq4JiXh5KxLyX3c6WKtnZPLKq/ch1JGFKMR2Fbdvk5W5p5qcd2NJLwaUEmPjopV3n5aAD/r7DGsn+wUhiUwk71YIRhSZyrIrOTNXFLZ/yIu5cr7qkBnEP1YCD/oeSmNy6cz2uq8kag90M6RtOgJO4KFsJ0tOqW/OWs3h4eBoWxyRzKVZHY/FyNSeOgKN8ZodkRlP0Tjm2oPqtaxJcvE3O8TG5jkKlCopk/q8pd/lYUP8k0W1R+LYc2njh6NMc+plmH/6qrI7Ep5AzuU89PhDoQY8WemqogyABqtnXQ+8yMIWkmQSHHB3I1WKegqGFNSXHoUyViONoy7FKdWmstpUfAtjPjXJl23g3WYkjeaKO4bPKZakKj2KUscPQUs8dOa0eggA0mxqLMHgZl9+UKqoC4e/7a+CdR3DMKlJjYFC/Zisfjxy++1gPC4Oh5BIP7QVT3atsgNkZynXAY+3qmF9/lyeWONzrPXdukanEZMwLi2UXIELHEQvPUv7aKgI","associated_data":"refund","nonce":"xaAOLXTSOskU"}}';
|
||
$header = '{"x-real-ip":"175.24.211.24","host":"sypt.lingruikj.com","x-forwarded-proto":"https","content-length":"840","user-agent":"Mozilla/4.0","content-type":"application/json","wechatpay-nonce":"gSSvoVuO1PPtuPtdFvvugy99YI1leUMF","wechatpay-timestamp":"1720086041","wechatpay-serial":"660FAD2D6E804E37BE9D77EF5882718CC1E3399F","wechatpay-signature":"Vatqwnzb0cYGMT1nOnpp086CUV8URBgWVeqPJW1tw/tt/w1htnnTs1lk0v+Z/i3cqpnkfr1XErzMQZ1yZXA7qH7nloRdjBYWLwJiwTrnrLDMLU//Oz1sUve4Mt910zIPGkMTbg2Zr+b6YXqPNVBYvFtjjRnBlqRpyVz07lsVDKA4Ygfslw+sZur4qC/yZy6d3fKwxIRy6S/GHBd+/kRnuagyjheuU+JZ32ScozXdt6AQF05S3VGzohiNvrIu48v9imlf3K6NdzGnSJPeiKQ9BSoOw0CkSl9idEYIIFfdbhbu9kc5l4V8bNQc45W8EUylXLT7cFa6B63+TZts5KOosw==","wechatpay-signature-type":"WECHATPAY2-SHA256-RSA2048","pragma":"no-cache","accept":"*/*"}';
|
||
|
||
$post_data = json_decode($post_data, true);
|
||
$header = json_decode($header, true);
|
||
|
||
raw_log('wechat_pay/requirement_refund_notify', ['post' => $post_data, 'header' => $header]);
|
||
|
||
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
|
||
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
|
||
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
|
||
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
|
||
|
||
$mch_id = getenv('MERCHANT_ID');
|
||
|
||
// 根据通知的平台证书序列号,查询本地平台证书文件,
|
||
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
|
||
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||
|
||
// 检查通知时间偏移量,允许5分钟之内的偏移
|
||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||
$verifiedStatus = Rsa::verify(
|
||
// 构造验签名串
|
||
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
|
||
$inWechatpaySignature,
|
||
$platformPublicKeyInstance
|
||
);
|
||
|
||
// 验签
|
||
if ($timeOffsetStatus && $verifiedStatus) {
|
||
// 使用PHP7的数据解构语法,从Array中解构并赋值变量
|
||
['resource' => [
|
||
'ciphertext' => $ciphertext,
|
||
'nonce' => $nonce,
|
||
'associated_data' => $aad
|
||
]] = $post_data;
|
||
// 加密文本消息解密
|
||
$inBodyResource = AesGcm::decrypt($ciphertext, getenv('API_V3'), $nonce, $aad);
|
||
// 把解密后的文本转换为PHP Array数组
|
||
$pay_result = json_decode($inBodyResource, true);
|
||
|
||
if ($pay_result['refund_status'] == 'SUCCESS') {
|
||
$order = RequirementOrder::where(['out_trade_no' => $pay_result['out_trade_no']])->findOrEmpty();
|
||
|
||
if ($order->isEmpty()) {
|
||
throw new Exception('未找到订单' . $pay_result['out_trade_no']);
|
||
}
|
||
if ($order->pay_status != 1) {
|
||
throw new Exception('订单状态错误-' . $order->pay_status . $pay_result['out_trade_no']);
|
||
}
|
||
|
||
if ($order->is_refund != 0) {
|
||
throw new Exception('订单退款状态错误-' . $order->is_refund . $pay_result['out_trade_no']);
|
||
}
|
||
|
||
if ($order->refund_amount * 100 != $pay_result['amount']['total']) {
|
||
throw new Exception('退款金额不一致-' . $pay_result['out_trade_no']);
|
||
}
|
||
|
||
$order->save([
|
||
'refund_transaction_id' => $pay_result['refund_id'],
|
||
'is_refund' => 1,
|
||
'refund_time' => date('Y-m-d H:i:s', strtotime($pay_result['success_time'])),
|
||
]);
|
||
|
||
$requirement = Requirement::where(['id' => $order->requirement_id])->findOrEmpty();
|
||
if (!$requirement->isEmpty()) {
|
||
$requirement->save([
|
||
'requirement_pay_order_status' => 3
|
||
]);
|
||
if ($order->deposit_pay_status == 3) {
|
||
//保证金已退款,更新需求状态为已退款
|
||
$requirement->save([
|
||
'status' => 5
|
||
]);
|
||
}
|
||
}
|
||
|
||
return json('success');
|
||
}
|
||
} else {
|
||
throw new Exception('验签失败');
|
||
}
|
||
|
||
} catch (Exception $e) {
|
||
var_dump($e->getMessage());
|
||
raw_log('wechat_pay/requirement_refund_notify_error', ['exception' => $e->getMessage()]);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @desc 保证金订单回调
|
||
* @param Request $request
|
||
* @return void
|
||
*/
|
||
public function requirement_deposit_notify(Request $request)
|
||
{
|
||
try {
|
||
$post_data = $request->post();
|
||
$header = $request->header();
|
||
raw_log('wechat_pay/requirement_notify', ['post' => $post_data, 'header' => $header]);
|
||
|
||
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
|
||
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
|
||
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
|
||
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
|
||
|
||
$mch_id = getenv('MERCHANT_ID');
|
||
|
||
// 根据通知的平台证书序列号,查询本地平台证书文件,
|
||
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
|
||
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||
|
||
// 检查通知时间偏移量,允许5分钟之内的偏移
|
||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||
$verifiedStatus = Rsa::verify(
|
||
// 构造验签名串
|
||
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
|
||
$inWechatpaySignature,
|
||
$platformPublicKeyInstance
|
||
);
|
||
// 验签
|
||
if ($timeOffsetStatus && $verifiedStatus) {
|
||
|
||
|
||
}
|
||
|
||
|
||
} catch (Exception $e) {
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @desc 拍照服务支付回调
|
||
* @param Request $request
|
||
* @return void
|
||
*/
|
||
public function photo_notify(Request $request)
|
||
{
|
||
try {
|
||
$post_data = $request->post();
|
||
$header = $request->header();
|
||
raw_log('wechat_pay/photo_notify', ['post' => $post_data, 'header' => $header]);
|
||
|
||
} catch (Exception $e) {
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @desc 支付保证金回调
|
||
* @param Request $request
|
||
* @return void
|
||
*/
|
||
public function photo_deposit_notify(Request $request)
|
||
{
|
||
try {
|
||
$post_data = $request->post();
|
||
$header = $request->header();
|
||
raw_log('wechat_pay/photo_deposit_notify', ['post' => $post_data, 'header' => $header]);
|
||
|
||
//@todo:支付成功更新拍照服务中保证金状态
|
||
|
||
} catch (Exception $e) {
|
||
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @desc 拍照退款
|
||
* @param Request $request
|
||
* @return void
|
||
*/
|
||
public function photo_refund_notify(Request $request)
|
||
{
|
||
try {
|
||
$post_data = $request->post();
|
||
$header = $request->header();
|
||
raw_log('wechat_pay/refund_notify', ['post' => $post_data, 'header' => $header]);
|
||
|
||
$inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取
|
||
$inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取
|
||
$inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取
|
||
$inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取
|
||
|
||
$mch_id = getenv('MERCHANT_ID');
|
||
|
||
// 根据通知的平台证书序列号,查询本地平台证书文件,
|
||
$platformCertificateFilePath = 'file://' . base_path() . '/certificate/wechatpay_660FAD2D6E804E37BE9D77EF5882718CC1E3399F.pem';
|
||
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||
|
||
// 检查通知时间偏移量,允许5分钟之内的偏移
|
||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||
$verifiedStatus = Rsa::verify(
|
||
// 构造验签名串
|
||
Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, json_encode($post_data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)),
|
||
$inWechatpaySignature,
|
||
$platformPublicKeyInstance
|
||
);
|
||
// 验签
|
||
if ($timeOffsetStatus && $verifiedStatus) {
|
||
|
||
|
||
}
|
||
|
||
|
||
} catch (Exception $e) {
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @desc 拍照订单保证金退款回调
|
||
* @param Request $request
|
||
* @return void
|
||
*/
|
||
public function photo_deposit_refund_notify(Request $request)
|
||
{
|
||
try {
|
||
|
||
}catch (Exception $e){
|
||
|
||
}
|
||
}
|
||
|
||
} |