결제 스캔 후 콜백하는 PHP WeChat 결제 개발 방법(모드 2)

高洛峰
풀어 주다: 2017-03-09 15:40:37
원래의
3415명이 탐색했습니다.

사실 이 글을 쓸 당시에는 이미 시대에 뒤처져 있다는 생각이 들었습니다. 그런데 바이두에서 "위챗 결제 개발 - 결제 스캔 후 콜백하는 방법(모드2)"을 검색해 보니, 답변을 하자면, 많은 친구들이 여전히 이 문제를 해결하지 못했다는 것을 알았으므로 내 솔루션 아이디어를 모든 사람과 공유하겠습니다.

1. WeChat 결제 SDK를 다운로드합니다. (저자는 PHP 개발을 예로 사용하며 SDK 패키지는 WxpayAPI_php_v3.zip입니다.)

SDK 패키지를 다운로드하고 압축을 푼 디렉터리에 압축을 풉니다. 다음 디렉터리를 볼 수 있습니다

결제 스캔 후 콜백하는 PHP WeChat 결제 개발 방법(모드 2)

2. WeChat 결제 개발자 문서를 참조한 후 위챗 스캔 코드 결제 데모가 예제의 Native.php 파일이라는 것을 알게 되었습니다. 디렉토리

편의상 압축을 푼 파일 전체를 로컬 환경의 루트 디렉토리에 있는 wxpay(개인 취향에 따라 이름 지정 가능) 폴더에 넣어주면 됩니다

3 . 저자를 예로 들어 브라우저에 http://localhost/wxpay/example/native.php

를 입력하면 위의 URL을 열어보니 아래와 같이 2개의 QR코드가 있는 것을 발견했습니다. 제목에서 알 수 있듯이 오늘 우리가 공부하는 것은 모드 2 스캔 코드입니다. (공식 모드 2 스캔 코드에서도 결제를 권장합니다.)

4. 휴대폰으로 위챗에 로그인하고 QR 코드를 스캔합니다. 위 페이지에서 모드 2를 선택하고

여기서 흥미로운 문제를 발견했습니다. 결제가 성공한 후에도 PC 페이지에는 아무런 변화가 없기 때문에 우리가 고려하는 주요 문제는 어떻게 콜백하는가입니다. 지불 후.

여기서 너무 헛소리는 하지 않겠습니다. 저자는 인터넷에 있는 여러 가지 방법을 참고하여 다음과 같이 요약했습니다.

1. 1.native.php 파일에는 일부 html, 스캔 코드 모드 2의 일부 관련 html 코드만 남습니다.

2. 공식 문서에도 스캔 코드 모드 2의 결제 결과가 비동기식 응답으로 결제 결과를 적극적으로 반환하지 않는다고 명시되어 있으므로, 결제 결과를 수시로 모니터링하기 위해 javascript를 사용합니다. 그런 다음 요청 결과에 따라 다음 페이지 콜백을 수행합니다. 작성자의 최종 코드는 다음과 같습니다. 관심 있는 친구들은

native.php 파일

<?php
ini_set(&#39;date.timezone&#39;,&#39;Asia/Shanghai&#39;);
//error_reporting(E_ERROR);

require_once "../lib/WxPay.Api.php";
require_once "WxPay.NativePay.php";
require_once &#39;log.php&#39;;

//模式一
/**
 * 流程:
 * 1、组装包含支付信息的url,生成二维码
 * 2、用户扫描二维码,进行支付
 * 3、确定支付之后,微信服务器会回调预先配置的回调地址,在【微信开放平台-微信支付-支付配置】中进行配置
 * 4、在接到回调通知之后,用户进行统一下单支付,并返回支付信息以完成支付(见:native_notify.php)
 * 5、支付完成之后,微信服务器会通知支付成功
 * 6、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
 */
$notify = new NativePay();
$url1 = $notify->GetPrePayUrl("123456789");

//模式二
/**
 * 流程:
 * 1、调用统一下单,取得code_url,生成二维码
 * 2、用户扫描二维码,进行支付
 * 3、支付完成之后,微信服务器会通知支付成功
 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
 */
$input = new WxPayUnifiedOrder();
$input->SetBody("1分钱购买何宁");
$input->SetAttach("1分钱购买何宁");
$num=WxPayConfig::MCHID.date("YmdHis");
$input->SetOut_trade_no($num);
$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("NATIVE");
$input->SetProduct_id("123456789");
$result = $notify->GetPayUrl($input);
$url2 = $result["code_url"];
?>

<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1" /> 
    <title>微信支付样例</title>
</head>
<body>
    <div style="margin-left: 10px;color:#556B2F;font-size:30px;font-weight: bolder;">扫描支付模式二</div><br/>
    <img alt="模式二扫码支付" src="qrcode.php?data=<?php echo urlencode($url2);?>"   style="max-width:90%"/>
    <div id="myDiv"></div><div id="timer">0</div>
    <script>  
    //设置每隔1000毫秒执行一次load() 方法  
    var myIntval=setInterval(function(){load()},1000);  
    function load(){  
       document.getElementById("timer").innerHTML=parseInt(document.getElementById("timer").innerHTML)+1; 
        var xmlhttp;    
        if (window.XMLHttpRequest){    
            // code for IE7+, Firefox, Chrome, Opera, Safari    
            xmlhttp=new XMLHttpRequest();    
        }else{    
            // code for IE6, IE5    
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");    
        }    
        xmlhttp.onreadystatechange=function(){    
            if (xmlhttp.readyState==4 && xmlhttp.status==200){    
                trade_state=xmlhttp.responseText;  
                if(trade_state==&#39;SUCCESS&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;支付成功&#39;;  
                    //alert(transaction_id);  
                    //延迟3000毫秒执行tz() 方法
                    clearInterval(myIntval);  
                    setTimeout("location.href=&#39;success.php&#39;",3000);  

                }else if(trade_state==&#39;REFUND&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;转入退款&#39;; 
                    clearInterval(myIntval); 
                }else if(trade_state==&#39;NOTPAY&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;请扫码支付&#39;;  
                      
                }else if(trade_state==&#39;CLOSED&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;已关闭&#39;;  
                    clearInterval(myIntval);
                }else if(trade_state==&#39;REVOKED&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;已撤销&#39;;  
                    clearInterval(myIntval);
                }else if(trade_state==&#39;USERPAYING&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;用户支付中&#39;;  
                }else if(trade_state==&#39;PAYERROR&#39;){  
                    document.getElementById("myDiv").innerHTML=&#39;支付失败&#39;; 
                    clearInterval(myIntval); 
                }  
                 
            }    
        }    
        //orderquery.php 文件返回订单状态,通过订单状态确定支付状态  
        xmlhttp.open("POST","orderquery.php",false);    
        //下面这句话必须有    
        //把标签/值对添加到要发送的头文件。    
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");    
        xmlhttp.send("out_trade_no=<?php echo $num;?>");  
         
        }  
    </script>
    
</body>
</html>
로그인 후 복사

을 참고할 수 있습니다. orderquery.php 코드도 그에 따라 조정되었습니다.

<?php
ini_set(&#39;date.timezone&#39;,&#39;Asia/Shanghai&#39;);
error_reporting(E_ERROR);
require_once "../lib/WxPay.Api.php";
require_once &#39;log.php&#39;;
 
//初始化日志
$logHandler= new CLogFileHandler("./logs/".date(&#39;Y-m-d&#39;).&#39;.log&#39;);
$log = Log::Init($logHandler, 15);
 
function printf_info($data)
{
    foreach($data as $key=>$value){
        echo "<font color=&#39;#f00;&#39;>$key</font> : $value <br/>";
    }
}
 
 
if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){
    $transaction_id = $_REQUEST["transaction_id"];
    $input = new WxPayOrderQuery();
    $input->SetTransaction_id($transaction_id);
    //printf_info(WxPayApi::orderQuery($input));
    $result=WxPayApi::orderQuery($input);
    echo $result[&#39;trade_state&#39;];
    exit();
}
 
if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){
    $out_trade_no = $_REQUEST["out_trade_no"];
    $input = new WxPayOrderQuery();
    $input->SetOut_trade_no($out_trade_no);
    //printf_info(WxPayApi::orderQuery($input));
    $result=WxPayApi::orderQuery($input);
    echo $result[&#39;trade_state&#39;];
    exit();
}
?>
로그인 후 복사

새 Success.php 파일:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>微信支付成功</title>
</head>
 
<body>
<br /><br /><br /><br /><br /><br /><br />
<h1>微信支付成功</h1>
</body>
</html>
로그인 후 복사

위는 작성자가 정리한 코드입니다. 디버깅 후 문제가 없는 것으로 확인되었습니다. 관심있는 친구들은 그것을 참고할 수 있습니다.


위 내용은 결제 스캔 후 콜백하는 PHP WeChat 결제 개발 방법(모드 2)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!