-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
支付宝支付当subject为中文时,异步通知subject乱码导致验签失败 #14
Comments
刚刚对中文问题进行了测试。但是未重现您说的验签失败问题。 测试如下: <?php
namespace App\Http\Controllers;
use Pay;
use Log;
use Illuminate\Http\Request;
class UsersController extends Controller
{
public function index(Request $request)
{
$config_biz = [
'out_trade_no' => time(),
'total_amount' => '1',
'subject' => '测试用例',
];
return Pay::driver('alipay')->gateway()->pay($config_biz);
}
public function return(Request $request)
{
$o = Pay::driver('alipay')->gateway()->verify($request->all());
dd($o);
}
public function notify(Request $request)
{
if (Pay::driver('alipay')->gateway()->verify($request->all())) {
file_put_contents(storage_path('notify.txt'), "收到来自支付宝的异步通知\r\n", FILE_APPEND);
file_put_contents(storage_path('notify.txt'), '订单号:' . $request->out_trade_no . "\r\n", FILE_APPEND);
file_put_contents(storage_path('notify.txt'), '订单标题:' . $request->subject . "\r\n", FILE_APPEND);
file_put_contents(storage_path('notify.txt'), '订单金额:' . $request->total_amount . "\r\n\r\n", FILE_APPEND);
} else {
file_put_contents(storage_path('notify.txt'), "收到来自异步通知,not verify\r\n", FILE_APPEND);
}
echo "success";
}
} 最后 notify.txt 文件收到:
表明支付宝异步通知所使用的是 utf8 的编码,从同步通知结果也能看到 麻烦您详细描述下您所使用的环境及代码,以便确定问题所在,谢谢! 感谢您的支持! |
gateway 为scan时 |
<?php
namespace Yansongda\Pay\Gateways\Alipay;
use Yansongda\Pay\Contracts\GatewayInterface;
use Yansongda\Pay\Exceptions\GatewayException;
use Yansongda\Pay\Exceptions\InvalidArgumentException;
use Yansongda\Pay\Support\Config;
use Yansongda\Pay\Traits\HasHttpRequest;
abstract class Alipay implements GatewayInterface
{
...
protected function getResult($config_biz, $method)
{
$this->config['biz_content'] = json_encode($config_biz);
$this->config['method'] = $method;
$this->config['sign'] = $this->getSign();
$method = str_replace('.', '_', $method).'_response';
$this->gateway = $this->gateway."?charset=utf-8";
$data = json_decode(
mb_convert_encoding($this->post($this->gateway, $this->config), 'utf-8', 'gb2312'),
true
);
if (!isset($data[$method]['code']) || $data[$method]['code'] !== '10000') {
throw new GatewayException(
'get result error:'.$data[$method]['msg'].' - '.$data[$method]['sub_code'],
$data[$method]['code'],
$data);
}
return $this->verify($data[$method], $data['sign'], true);
}
} 在gateway后拼接 |
翻了整个官方文档中,并未有 同时,post 参数中已经带有 所以,为了严谨性,将不会采用这种方案。 刚刚测试了下,发现验签是通过的,但是,最后得到的 notify.txt 已经乱码,内容如下:
已经基本可以确定是编码问题。 请问您确定验签不通过吗? @shizhice 请问您这边也验签不通过吗? |
对。编码错误,导致验签失败。 |
我查看了post参数中确实有 <form id="alipaysubmit" name="alipaysubmit" action="https://openapi.alipay.com/gateway.do?charset=utf-8" method="POST">
...
<input type="hidden" name="method" value="alipay.trade.wap.pay" />
<input type="hidden" name="format" value="json" />
<input type="hidden" name="charset" value="utf-8" />
<input type="hidden" name="sign_type" value="RSA2" />
<input type="hidden" name="version" value="1.0" />
...
</form>
<script>document.forms['alipaysubmit'].submit();</script> 故而临时采用方案 $this->gateway = $this->gateway."?charset=utf-8"; |
@shizhice 我看看官方 SDK 先,看看能不能找到解决方案,web 和 wap 的那个是官方 SDK 中的,所以就直接扣下来了。 奇怪,我这边验签居然是通过的。 感谢您的支持! |
@yansongda 不好意思啊,我刚才又看了一下,我这里也是验签成功的,我是将 |
@yansongda 另外我认为有一个优化的地方,当支付宝支付成功的时候,支付宝会异步通知我们,但是支付宝会通知我们两次。 {"trade_status":"WAIT_BUYER_PAY"} 和 {"trade_status":"TRADE_SUCCESS"} 新手可能会忽略这个问题,望在readme中添加下说明在收到支付宝异步通知时判断下 |
是的,扫码时,的确会异步通知两次,一般情况下,需要对官方文档熟悉,不然即使这个地方提醒了,也是不 ok 的,不过您说的对,稍后我再 readme 中做出说明。 经检查,官方 SDK 中直接将 charset 放入 get 中: //系统参数放入GET请求串
$requestUrl = $this->gatewayUrl . "?";
foreach ($sysParams as $sysParamKey => $sysParamValue) {
$requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&";
}
$requestUrl = substr($requestUrl, 0, -1); 不得不说,官方的文档及 SDK 真实让人抓狂~ 稍后将进行修复。 感谢大家的支持!谢谢! |
官方的sdk如果那么优雅、实用的话,我们还造什么轮子。😁😁😁 |
public function pay($endpoint, array $payload): Response
{
$payload['method'] = $this->getMethod();
$payload['biz_content'] = json_encode(array_merge(
json_decode($payload['biz_content'], true),
['product_code' => $this->getProductCode()]
));
$payload['sign'] = Support::generateSign($payload, $this->config->get('private_key'));
Log::debug('Paying A Web/Wap Order:', [$endpoint, $payload]);
return $this->buildPayHtml($endpoint, $payload);
} biz_content使用json_encode编码时,中文会被转换掉,异步通知时的中文就会乱掉,导致验签失败 下面是我打印的日志:
|
@bqdove 麻烦请升级至最新版,同时,如果仍有问题,请按照 issue 模板重新发 issue。 感谢支持! |
支付宝异步通知数据,charset为GBK,subject为乱码,导致验签失败。当subject为英文时,验签通过。
The text was updated successfully, but these errors were encountered: