-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: