본 글은 위챗 결제 PHP SDK의 위챗 공용계좌 결제 구현 코드에 대한 관련 정보를 주로 소개합니다. 도움이 필요한 친구는 참고하시기 바랍니다
이미 위챗 결제를 신청하신 것으로 가정합니다
1. 위챗 배경 구성은 그림과 같습니다
먼저 테스트해보겠습니다. 먼저 테스트 인증 디렉터리를 넣고 테스트 화이트리스트를 추가하세요. 테스트 인증 디렉터리는 WeChat 요청을 시작하려는 파일이 있는 디렉터리입니다.
예를 들어 jsapi jsapi.php가 있는 디렉터리는 일반적으로 요청 시 테스트 디렉터리입니다. 테스트 허용 목록은 개발자의 WeChat 계정입니다.
공식 결제 승인 디렉토리는 테스트 디렉토리와 동일할 수 없습니다. 그렇지 않으면 오류가 보고됩니다. 잘못된 인증 디렉터리 및 테스트 화이트리스트를 입력하거나 입력하지 못하면 오류가 발생합니다.
오류 보고 예:
NaNsystem:access_denied
테스트 허용 목록에 없음
2. lib/WxPay.Config.php 파일을 구성합니다
가장 중요한 구성은 다음 4가지 항목입니다.
const APPID = '';
const MCHID = '';
const KEY = '';
const APPSECRET = '';
APPID와 APPSECRET은 둘 다 가능 WeChat 백엔드에서 찾을 수 있습니다.
MCHID는 WeChat 결제 신청 후 전송된 이메일에서 확인할 수 있습니다. KEY는 이메일 프롬프트
에 따라 판매자 플랫폼에서 구성할 수 있습니다.
3. 시작하는 index.php에 접속하세요
index.php에 먼저 접속하시면 인터페이스를 보실 수 있습니다
가장 먼저 필요한 것은 JSAPI 결제입니다. 하지만 index.php 코드 하단의 링크를 살펴보세요. 기본적으로는 데모 링크로 설정되어 있습니다.
<ul> <li style="background-color:#FF7F24"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/jsapi.php';?>">JSAPI支付</a></li> <li style="background-color:#698B22"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/micropay.php';?>">刷卡支付</a></li> <li style="background-color:#8B6914"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/native.php';?>">扫码支付</a></li> <li style="background-color:#CDCD00"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/orderquery.php';?>">订单查询</a></li> <li style="background-color:#CD3278"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/refund.php';?>">订单退款</a></li> <li style="background-color:#848484"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/refundquery.php';?>">退款查询</a></li> <li style="background-color:#8EE5EE"><a href="<?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/download.php';?>">下载订单</a></li> </ul>
물론 직접 액세스 링크로 작성할 수도 있습니다.
4. JSAPI 결제
필요한 코드 분석:
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log'); $log = Log::Init($logHandler, 15);
전화로그 클래스는 $log->DEBUG('test');를 통해 디버깅 정보를 인쇄할 수 있습니다. 실제로 $Log::DEBUG('test');를 직접 사용하여
$tools = new JsApiPay(); $openId = $tools->GetOpenid();
를 주로 GetOpenid() 함수 에서 얻을 수 있습니다. 🎜> WxPay.JsApiPay.php 파일
public function GetOpenid() { //通过code获得openid if (!isset($_GET['code'])){ //触发微信返回code码 $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']); $url = $this->CreateOauthUrlForCode($baseUrl); Header("Location: $url"); exit(); } else { //获取code码,以获取openid $code = $_GET['code']; $openid = $this->getOpenidFromMp($code); return $openid; } }
$baseUrl에 정의된 것은 실제로 이 페이지로 다시 이동하는 것입니다. CreateOauthUrlForCode() 함수를 계속 추적할 수 있습니다. 실제로 WeChat의 Auth2.0
참조 링크: http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75를 통해 Openid를 얻을 수 있습니다. html
WeChat의 웹 인증 인터페이스를 설정해야 합니다.
Openid를 획득한 후 WeChat Pay의 통합 주문 인터페이스를 호출할 수 있습니다. jsapi.php 파일로 돌아가서 다음 코드는
$input = new WxPayUnifiedOrder(); $input->SetBody("test"); $input->SetAttach("test"); $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis")); $input->SetTotal_fee("1"); $input->SetTime_start(date("YmdHis")); $input->SetTime_expire(date("YmdHis", time() + 600)); $input->SetGoods_tag("test"); $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php"); $input->SetTrade_type("JSAPI"); $input->SetOpenid($openId); $order = WxPayApi::unifiedOrder($input); echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>'; printf_info($order); $jsApiParameters = $tools->GetJsApiParameters($order);
입니다. 내부 코드는
$input->SetAttach("test");
입니다. 값을 $input->SetAttach("test this is attachment");로 변경하면 버그가 있을 것입니다. 사실 이 매개변수는 필요하지 않으며 간단히 제거할 수 있습니다.
코드:
$input->SetNotify_url(http://paysdk.weixin.qq.com/example/notify.php);
는 결제 결과 알림을 받도록 설정된 URL입니다. 다음은 기본 데모 링크로 설정할 수 있습니다. >
$input->SetNotify_url(dirname('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'/notify.php');
当然你也可以选择直接写死。
其中的函数 unifiedOrder($input) 可以到WxPay.Api.php 中文件跟踪,其实就是调用统一下单接口。
在 WxPay.Api.php 中需要更改的一处代码是:
//异步通知url未设置,则使用配置文件中的url if(!$inputObj->IsNotify_urlSet()){ $inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//异步通知url }
就是当没设置 notifyUrl 的时候回去配置文件中找,但是配置文件中根本没有设置。
所以你可以选择在 配置文件WxPay.Config.php 中加上这个配置,也可以直接写一个默认的notify链接。
函数 GetJsApiParameters() 是获取jsApi支付的参数给变量 $jsApiParameters 方便在下面的Js中调用
jsapi.php 中js的代码:
function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', <?php echo $jsApiParameters; ?>, function(res){ WeixinJSBridge.log(res.err_msg); alert(res.err_code+res.err_desc+res.err_msg); } ); } function callpay() { if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } }else{ jsApiCall(); } }
其中点击立即支付按钮调用的就是 callpay() 函数,他有会调用jsApiCall() 函数打开支付程序。
此后输入密码完成支付。
在完成支付页面点击完成会回到这个支付页面,并弹出 支付成功的提示框
这个其实就是 js函数 jsApiCall 里面的alter 弹出的对话框
其中 res.err_msg 为get_brand_wcpay_request:ok 表明前端判断的支付成功,我们可以根据这个将支付跳转到成功页面。
但是这个并不可信。确认是否支付成功还是应当 通过notify.php 处理业务逻辑。
5. 支付结果通知 notify.php
其实这个页面最主要的代码就两行
$notify = new PayNotifyCallBack(); $notify->Handle(false);
其中大部分逻辑在 Handle 函数中处理 文件 WxPay.Notify.php
final public function Handle($needSign = true) { $msg = "OK"; //当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败 $result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg); if($result == false){ $this->SetReturn_code("FAIL"); $this->SetReturn_msg($msg); $this->ReplyNotify(false); return; } else { //该分支在成功回调到NotifyCallBack方法,处理完成之后流程 $this->SetReturn_code("SUCCESS"); $this->SetReturn_msg("OK"); } $this->ReplyNotify($needSign); }
主要代码:
$result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);
跟踪函数 notify 文件WxPay.Api.php
public static function notify($callback, &$msg) { //获取通知的数据 $xml = $GLOBALS['HTTP_RAW_POST_DATA']; //如果返回成功则验证签名 try { $result = WxPayResults::Init($xml); } catch (WxPayException $e){ $msg = $e->errorMessage(); return false; } return call_user_func($callback, $result); }
通过 $GLOBALS[‘HTTP_RAW_POST_DATA‘]; 获取同志数据 然后 Init 函数验证签名等。验签成功运行代码
return call_user_func($callback, $result);
即调用了一个回调函数,NotifyCallBack() 函数并传递参数 $result 在NotifyCallBack函数中会调用我们重写的NotifyProcess()函数(此函数在notify.php 中被重写)
NotifyProcess() 判断也没有问题就会 设置返回 success的xml信息
$this->SetReturn_code("SUCCESS"); $this->SetReturn_msg("OK");
并最终调用函数 $this->ReplyNotify($needSign); echo success的结果
函数ReplyNotify 需要修改一处代码:
final private function ReplyNotify($needSign = true) { //如果需要签名 if($needSign == true && $this->GetReturn_code($return_code) == "SUCCESS") { $this->SetSign(); } WxpayApi::replyNotify($this->ToXml()); } $this->GetReturn_code($return_code) == "SUCCESS")
改为
$this->GetReturn_code() == "SUCCESS")
即可。
这样整个流程就结束了。上面提到了 传递订单参数
$input->SetAttach("test");
如果我设置 值为 test this is attach (其实只要有空格就会存在bug)
如图 传递的订单信息
可以看到 attach 信息正常,当然支付也是正常的没有任何问题。
但是发现总是会收到notify 通知,即意味着没有返回给微信服务器正确的结果通知。
打印服务器发来的通知数据
可以看到 attach 是 test+this+is+attach 即空格被转化为加号
打印接收到的签名和程序算出来的签名发现 签名不同,即认为接收结果异常。
所以我们要是想使用attach 这个值就不能有空格,要么干脆不使用这个参数
(等待微信修复这个bug, 也可能是我这边有哪个地方不会? - -#)
这样 微信支付的 JsApi支付就大致分析完成了。
위 내용은 WeChat 결제 PHP SDK의 WeChat 공개 계정 결제 구현 코드 정보의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!