标签 wechat 下的文章

回调的通知发现没有被正确处理,查看才知道<req_info>是经过加密的要自行解密

文档:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10

文中只有简单一句带过, 查了一下自带的 PHP SDK 也没有相关的代码

用key*对加密串B做AES-256-ECB解密(PKCS7Padding)

实现起来其实不难,就下面几行而已

define("PAY_KEY","3a6fbc07d5*********");
$hash = 'sjACArtC1yjo/WAlEnKyOcqP+avFCOCRR7Tn...AqXwmjIbonF/ECEqqs='; //密文
$strA = base64_decode($hash2);
$md5key = md5(PAY_KEY);
$raw = openssl_decrypt($strA,'AES-256-ECB',$md5key, OPENSSL_RAW_DATA); //解密的原文

解密出的原文:

<root>
<out_refund_no><![CDATA[202012281002345G4Y7R]]></out_refund_no>
<out_trade_no><![CDATA[202012281002345G4Y7R]]></out_trade_no>
<refund_account><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]></refund_account>
<refund_fee><![CDATA[2]]></refund_fee>
<refund_id><![CDATA[50300406842020122805052137399]]></refund_id>
<refund_recv_accout><![CDATA[支付用户零钱]]></refund_recv_accout>
<refund_request_source><![CDATA[API]]></refund_request_source>
<refund_status><![CDATA[SUCCESS]]></refund_status>
<settlement_refund_fee><![CDATA[2]]></settlement_refund_fee>
<settlement_total_fee><![CDATA[2]]></settlement_total_fee>
<success_time><![CDATA[2020-12-28 22:05:57]]></success_time>
<total_fee><![CDATA[2]]></total_fee>
<transaction_id><![CDATA[4200000791202012284085971964]]></transaction_id>
</root>

不是什么难点,关键在于要给第四参数 OPENSSL_RAW_DATA 网上查到很多的方法至少前几页的都不对,要么是差最后一点要么舍近求远化简为繁。

特此备忘一下。

微信公众号开发中有会遇到使用多媒体素材的问题,例如语音、视频、图片等。不知道该说微信素材管理的设计是恶心还是谨慎,公众号后台明明有同样的功能,但是后台的图文和媒体文件素材和公众号的调用的资源是相互不互通的。如果要公众号响应脚本给用户回一个图片或视频,就必须自己实现多媒体文件的上传,换领media_id 而不能从公众号后台上传获得。

不去深究这样设计的原因,只谈解决办法。为每个管理的项目额外开发一个上传管理的程序有大费周章。今天试了下用postman直接调用接口,可行! 备忘步骤如下。

1 设置调用接口的IP白名单

公众号后台 -> 开发 -> 基本配置 -> IP白名单

把自己的IP加进去

2 GET请求获得 access_token

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

两参数从公众号后台上一步的基本配置页面获得

结果如图
QQ截图20201029173346.jpg

3 POST请求获得media_id

https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE

复制出上一步骤的access_token 替换进参数内,本次需求上传的是图片,所以type为 image

https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=38_gW19v-VusU3SHhVP4w_JvHvNSfR_XC-DazL1IYpb18SUZ3myrHM_exn1NocgtOFV8xOiLFFZL39J3YkrDMHRuCUbg2gYDlo3r5pIXKIxV-8kSJQjhVKa8LFzkDv8y7jp1bZ9Gp2xUUEddjNCZEZhCBANSN&type=image

保险起见,我在get和post参数都保留了 access_token 和 type, 并且在 post参数按API文档要求增加一个media的参数,修改类型为file,点value栏选择要上传的文件。然后提交。 成功获得 media_id 如下图

QQ截图20201029171656.jpg

参考文:

https://www.jianshu.com/p/8602d75b58ba

https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/Adding_Permanent_Assets.html

用chrome从甲方提供的网页上保存了一批图片素材用于制作H5活动页。发布后反馈iOS上部分图片不显示,自己测试确实如此,找微信客服也抓头没办法解决只给了一些常规套路让我检查是不是文件太大,路径有中文、文件名大小写之类的问题。

最离谱的是 图片url直接在微信里也是打不开的,用图像处理软件处理过(tinypng压缩)也还是不显示。但是在安卓和PC端的开发工具上显示则正常。

情况实在太诡异,最后用文本工具直接打开图片,看到头部 RIFF ... WEBPVP8 !!! 恍然大悟

QQ截图20200928151342.png

Chrome保存的时候帮我转换成了 webp?!

试试直接在 Safari 里打开有问题的素材url ,果然是iOS自身不支持webp,也不能显示。

解决办法无他,webp-> jpeg/png 替换掉原素材,完事!

这个问题其实早在2016年已经遇到,在2018年知道原因盖棺定论。近日项目重新触及,备忘一下。

从jssdk或scope接口获得用户信息内的头像链接,如果直接用php的 file_get_contents 请求的话,通常会非常的慢,脚本运行大约30秒之后才能加载出图像。如果请求量大非常容易造成服务器的堵塞。

原因

摘录另一网友的日志:
https://www.cnblogs.com/mysic/p/5421754.html

微信的服务器对头像的资源请求返回的头信息是 Connection: keep-alive ,于是请求传输完数据后就一直在干等超时。
网上对这个问题求助的也不在少数,不知道腾讯是故意为之还是装作不知道,反正问题存在至今没有主动解决。

解决办法:

自欺欺人的解决办法:
这是我最早期的解决思路,在发起请求或者获得用户头像资源的最初即在后台预载这个资源到本地缓存,降低用户对等待延迟的感知。

老实人的解决办法:
改用curl请求到本地缓存处理,加上header,下载完主动截断链接。代码演示略

无效的解决办法:
给file_get_contents() 设置第三参数 context 指定关闭链接,设置了参数后,腾讯返回过来的是0字节的数据。我觉得它们故意的嫌疑更大了!

//实验证明 context 无效,会导致返回0字节
$context = stream_context_create(
    array("http" => 
        array(
            'method'=>'get',
            'header'=>'Connection: close\r\n'
        )
    )
);
$tmp_face_data = file_get_contents($face_url, false, $context);

目前在用的解决办法:

ini_set('default_socket_timeout', 1);
$tmp_face_data = file_get_contents($face_url);

也不是没有缺点,一个小小的瑕疵是要浪费额外的1秒等timeout,不过还可以接受。
另外有一个优点,这个参数不但对 file_get_contents 有效,对于 getimagesize 这个没有context参数的方法也有帮助
所以,一劳永逸。

结论:

腾信真TM会恶心人!

很简短的备忘, 通过 user-agent 来识别
但据说因为泄露私隐等原因(籍口) Chrome正在倡导淘汰 UA 新版的chrome-core 会丢弃这个头信息,我想到时我会因此再更新一篇博客吧

$isWechat = false;
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false){
    $isWechat = true;
}