Paypal支付接口回调IPN验证的PHP程序、微信调用报错请确认授权入口页所在域名、授权事件接收URL 40001invalid credential不合法的调用凭证问题

 一、Paypal支付接口回调 IPN 验证的 PHP程序

   这个网上也有不少代码,不过我看到很多采用fsockopen的方式调用的,但我在本地测试时发现返回:HTTP/1.0 302 Found,

HTTP/1.0 302 Found
Location: https://www.sandbox.paypal.com
Server: BigIP
Connection: close
Content-Length: 0

    而我们预期的返回应该是:VERIFIED或者INVALID字符串,看返回结果是跳转到https://www.sandbox.paypal.com 链接了,于是想着是不是用curl替换fscckopen方法。找了找curl的方法,这次能用了:

#回调Paypal校验支付有效性
public function verified($data){

	$req = 'cmd=_notify-validate';
	if(function_exists('get_magic_quotes_gpc')) $get_magic_quotes_exists = true;
	foreach ($data as $key => $value) {        
	   if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1){
	$value = urlencode(stripslashes($value)); 
	   }else{
			$value = urlencode($value);
	   }
	   $req.= "&$key=$value";
	}
	$ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
	curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
	curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
	curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
	$res = curl_exec($ch);	
	if (strcmp ($res, "VERIFIED") == 0) {
		return true;
	} else if (strcmp ($res, "INVALID") == 0) {
		return false;
	}
}

    上面我用的是沙盒验证的地址,正式地址要去掉sandbox。验证通过表示这个订单是通过paypal发送过来的,通过之后还需要再对金额数、币种、支付状态、收款人邮箱进行验证。以防注入。

二、微信报错:错误请确认授权入口页所在域名,

    微信报错:错误请确认授权入口页所在域名,与授权后回调页所在域名相同,并且,此两者都必须与申请第三方平台时填写的授权发起页域名相同。授权入口页所在域名:空。

    微信在进行第三方平台开发时,需要让平台使用者将自己的小程序授权给第三方平台,所以进行第三方平台开发时,要让用户扫描二维码来显示用户的小程序及公众号列表,并进行手动授权,在这过程中可能会遇害到报错: 错误请确认授权入口页所在域名,与授权后回调页所在域名相同,并且,此两者都必须与申请第三方平台时填写的授权发起页域名相同。授权入口页所在域名:空

代码如下:

//拿到appid,之类的配置数据
$conf = array(...);
//拿到一直在更新的token数据
$token = TOKEN;

#调用微信接口拿到pre_auth_code数据
$url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token={$token}";
$data  = array('component_appid'=>$conf['appid']);
$return = Http::post($url, json_encode($data));
$content = json_decode($return['content'], true);
$pre_auth_code = $content['pre_auth_code'];

#生成微信二维码的链接
include "lib/phpqrcode/phpqrcode.php";
$rurl="https://test.xcx.com/weixin/back";
$url="https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid={$conf['appid']}&pre_auth_code={$pre_auth_code}&redirect_uri={$rurl}&auth_type=3";

#调用二维码生成图片
include "phpqrcode/phpqrcode.php";
$errorCorrectionLevel="L";
$matrixPointSize="4";
QRcode::png($url, false, $errorCorrectionLevel, $matrixPointSize);

    此时生成的二维码图片,使用微信一扫就会提示上面的错误:如下

    其实原因很简单,微信不允许直接访问上面生成的URL,一定需要reffer,即来源URL。而且来源URL一定要和第三方平台里设置的一是一样的,所以只需要使用下面的代码替换上面的二给码生成工作,即微信不需要你来生成二维码图片,上面生成的这个URL打开就是微信的二维码图片界面,但是它要求来源的HTTP_REFERER数据必须不能为空且必须和第三方配置中的域名一样,代码示例如下:

#直接显示一个链接
echo "<div style='margin:0 auto;'><h2><a href='{$data}'>授权微信小程序</a></h2></div>";

上面的这链接打开直接就是微信的二维码界面。

三、微信第三方平台开发-授权事件接收URL解密蛋疼的-40001invalid credential不合法的调用凭证

    微信第三方平台开发时,先要进行创建第三方平台。并设置第三方的如:授权事件接收URL,消息校验Token,消息加解密Key,消息与事件接收URL,公众号开发域名,小程序服务器域名和小程序业务域名等,在创建第三方平台后,微信会进行推送component_verify_ticket。出于安全考虑,在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据。其调用的URL就是上面所提到的设置项授权事件接收URL所写的地址。

     开发者要在这个地址中拿到微信请求时所带的post数据和get数据。post的使用的是数据流,在php中需要使用file_get_contents("php://input");来取得,得到的是一个xml字符串,数据示例如下:

<xml>
    <AppId><![CDATA[abdf7rew8de2121e]]></AppId>
    <Encrypt><![CDATA[NDHIa5xBSeJ13yOEoBCtbQDkM/hxM4oUMfZDchfznat1tm9ECbA==]]></Encrypt>
</xml>

    微信请求URL时附带的参数如下:

array (
    'signature' => 'd0196718e9273e0edfe607eaf767437a895874ff',
    'timestamp' => '1125585476',
    'nonce' => '1705505263',
    'encrypt_type' => 'aes',
    'msg_signature' => 'abcb6b08226058493fede1a689175c494a425be1',
),

    开发者拿到上面的这些数据后需要调用微信提供的解密代码来进行解密,详见接口文档:

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=&lang=zh_CN

    其中核心文件WXBizMsgCrypt.php文件提供了WXBizMsgCrypt类的实现,是用户接入企业微信的接口类。demo.php提供了示例以供开发者参考。其它文件不用理会。WXBizMsgCrypt类封装了DecryptMsg, EncryptMsg两个接口,分别用于开发者解密以及开发者回复消息的加密。在上述拿到微信调用请求发送的数据之后,按照demo的示例进行解密:

//引入微信加解密文件
require("wxBizMsgCrypt.php");
//初始化类:这些参数都没有问题
$pc = new WXBizMsgCrypt($token, $encodingAesKey, $appid);
//尝试像demo中,提取post中Encrypt节点的加密字符串组建在format里试验
$xml_tree = new DOMDocument();
$xml_tree->loadXML($post);
$array_e = $xml_tree->getElementsByTagName('Encrypt');
$encrypt = $array_e->item(0)->nodeValue;
$format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
$from_xml = sprintf($format, $encrypt);
$errCode = $pc->decryptMsg($_GET['msg_signature'], $_GET['timestamp'], $_GET['nonce'], $format, $msg);
print($errCode . ":". $msg);

#尝试直接解密post过来的加密字符串
$errCode = $pc->decryptMsg($_GET['msg_signature'], $_GET['timestamp'], $_GET['nonce'], $post, $msg);
print($errCode . ":". $msg);

    但是上面的执行结果均是返回-40001错误, 非常蛋痛,从解密的文件xmlparse.php里的方法中可以看到出现-40001即是签名数据不对,即msg_signature传参不行。但是核对了所有的参数和方法,都没有发现我这里有什么问题,但是业务还得继续,可以先绕过这一块。如下直接调用解密(也可以注释掉微信包文件中的报错那行代码),先这样用着吧,40001真蛋痛!

#先绕过签名取得ComponentVerifyTicket值
require_once(ROOT_PATH .'pkcs7Encoder.php');
$pc = new Prpcrypt($encodingAesKey);
$result = $pc->decrypt($encrypt, $appid);
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值