이 글은 주로 PHP WeChat 결제의 개발 과정을 자세히 소개합니다. 관심 있는 친구들이 참고하면 도움이 될 것입니다.
1. 개발 환경
Thinkphp 3.2.3
WeChat: 서비스 계정, 인증
개발 도메인 이름: http://test.paywechat.com (맞춤 도메인 이름, 외부 네트워크에서 접근 불가)
2 . 관련 파일 및 권한이 필요합니다
활성화를 위해서는 WeChat 결제를 신청해야 합니다.
WeChat 공개 플랫폼 개발자 문서: http://mp.weixin.qq.com/wiki/home/index.html
WeChat 결제 개발자 문서: https: // pay.weixin.qq.com/wiki/doc/api/index.html
WeChat Payment SDK 다운로드 주소: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter= 11_1
3. 개발
WeChat Payment PHP 버전의 SDK를 다운로드합니다. 파일 디렉터리는 다음과 같습니다.
WeChat Payment SDK의 Cert 및 Lib 디렉터리를 Thinkphp에 넣습니다. 디렉터리는
입니다.
이제 WeChat 결제 승인 디렉터리 문제를 소개하겠습니다. 먼저 WeChat 결제 개발 구성에서 결제 승인 디렉터리
를 입력한 다음 js 인터페이스 보안을 입력합니다. 필드.
마지막으로 웹 인증 설정
이러한 설정이 완료되면 기본적으로 설정 디렉터리와 내 thinkphp의 디렉터리에 주의하세요.
4. WeChat 결제 구성
해당 구성을 올바르게 입력하세요.
[php] 보기 plain 복사
/**
* 계정 정보 구성
*/
WxPayConfig ==========================
//
/* *
* WeChat 공개 계정 정보 구성
*
* APPID : 결제가 연결된 APPID (필수 구성, 계좌 개설 이메일에서 확인 가능)
* 보기)
*
* 설정 주소 : https://pay.weixin.qq.com/index.php/account/api_cert
* 퍼블릭 플랫폼에 로그인하고 개발자 센터에서 설정),
* 주소 받기: https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @varstring
*/
const APPID = ''
const MCHID = ''
const KEY = '';
const APPSECRET = ''
//========[인증서 경로 설정]================================ =====
/**
*TODO: 판매자 인증서 경로 설정
* 인증서 경로는 절대 경로입니다. 경로를 입력해야 합니다. (환불 또는 주문 취소 시에만 필요하며, 가맹점 플랫폼에 로그인하여 다운로드할 수 있습니다.
*API 인증서 다운로드 주소 : https://pay.weixin.qq.com/index.php/account/api_cert, 다운로드 전 가맹점 운영 인증서 설치 필요)
* @var path
*/
const SSLCERT_PATH = '../cert/apiclient_cert' ;
const SSLKEY_PATH = '../cert/apiclient_key.pem'; 프록시 설정】=== =================== ==========
* TODO: 여기서 프록시 머신을 설정하세요. 프록시가 필요하지 않은 경우에만 설정하세요. 프록시가 필요하지 않으면 0.0.0.0 및 0
으로 설정하세요. 이 루틴은 컬을 사용합니다. HTTP POST 방법을 사용하여 프록시 서버를 여기에서 수정할 수 있습니다.
* 기본 CURL_PROXY_HOST=0.0.0.0 및 CURL_PROXY_PORT=0, 현재 프록시는 켜지지 않습니다(설정됨). 필요한 경우)
* @varknown_type
*/
const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";
const CURL_PROXY_PORT = 0;/ /8080;
//=======【신고 정보 구성】================= = =================
/**
* TODO: 인터페이스 호출 보고 수준, 기본 오류 보고(참고: 보고 시간 제한은 [1초], 성공 또는 실패에 관계 없이 보고[예외를 발생시키지 않음],
* 인터페이스 통화 프로세스에는 영향을 미치지 않습니다.) 보고를 활성화한 후에는 WeChat에서 요청 통화 품질을 모니터링하는 것이 편리합니다. 최소한
* 오류 보고를 활성화하는 것이 좋습니다.
* 보고 수준, 0. 보고 종료, 1. 오류만 보고됨 2. 전체 보고
* @var int
*/
const REPORT_LEVENL = 1
}
지금 코드 게시를 시작하세요:
[php] 보기 plain copy
namespace WechatController
useThinkCont 롤러;
/**
* 부모 클래스 컨트롤러, 상속 필요
* @file ParentController.class.php
* 게리
* @date 2015년 8월 4일
* @todu
*/
classParentController extendsController {
protected$options array (
'토큰 ' => '', // 암호화를 위한 EncodingAESKey 입력
'appid' => '앱비밀' =>
'디버그' => 거짓,
'logcallback' => ''
);
public $errCode = 40001;
public $errMsg = "접근 금지";
/**
* 获取access_token
* @return mixed|boolean|unknown
*/
public function getToken(){
$cache_token = S('exp_wechat_pay_token');
if(!empty($cache_token)){
return $cache_token;
}
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s &비밀=%s ';
$url = sprintf($url,$this->options['appid'], $this-> ;옵션['appsecret']);
$result = $this->http_get($url);
$result = json_decode($result,true);
if(empty($result)){
re 거짓으로 바꾸세요.
}
S('exp_wechat_pay_token',$result['access_token' ],array('유형' =>'파일','만료'=>3600));
return $result['access_token'];
}
/**
* 고객 서비스 메시지 보내기
* @param array $data 메시지 구조 {"touser":"OPENID","msgtype":"news","news": { ...}}
*/
public function sendCustomMessage( $data){
$token = $this->getToken();
if (empty($token)) return false;
$url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s';
$url = sprintf($url,$token);
$result = $this->http_post($url,self::json_encode($data));
if ($result)
{
$json = json_decode($result,true) ;
???$this->errCode = $json['errcode'];
$this$json['errmsg'];
return} return
;
false; }
/**
* 템플릿 메시지 보내기
* @param 알 수 없음 $data
* @return boolean|unknown
*/
public function sendTemplateMessage($data ){
$ token = $this->getToken();
if (empty($token)) return false;
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
$url = sprintf($url,$token);
$result = $this->http_post($url,self::json_encode($data));
if ($result)
{
$json = json_decode($result,true);
???$this->errCode = $json['errcode'];
$this$json['errmsg'];
return} return
;
false; }
public function getFileCache($name){
return S($name);
}
/**
* WeChat API는 중국어 이스케이프 json 구조를 지원하지 않습니다.
* @param array $arr
*/
static function json_encode( $arr) {
$parts = array ();
$is_list = false;
//주어진 배열이 숫자형 배열인지 알아보세요
$keys = array_keys ( $arr );
$max_length = count ( $arr ) - 1;
if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //첫 번째 키가 0이고 마지막 키가 길이인지 확인하세요. 길이가 1
$is_list = true입니다.
for($i = 0; $i count ( $keys ); $i ++) { //각 키가 해당 위치에 해당하는지 확인하세요
if($i != $keys [$i]) { //A 키가 위치 확인 시 실패합니다.
$is_list = false; //연관 배열입니다.
break;
}
}
}
foreach ( $arr as $key => $value ) {
if( is_array ( $value )) { //배열에 대한 맞춤 처리
if( $is_list)
$parts [] = self::json_encode ( $value ); /* :재귀: */
else
$parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :재귀: */
} else {
$str = '';
if (! $is_list)
$str = '"' . $key . '":';
//여러 데이터 유형에 대한 맞춤 처리
if (!is_string ( $value ) && is_numeric ( $value ) && $value
$str .= $value; //Numbers
elseif ($value === false)
$str .= '거짓' ; //부울
elseif ($value === true)
$str .= '참' ;
else
$str .= '"' . 슬래시 추가 ( $value ) . '"' ; //기타 모든 것
// :TODO: 우리가 주의해야 할 데이터 유형이 더 있나요? (개체?)
$parts [] = $str;
}
}
$json = 내파( , $parts );
if ($is_list)
return '[' $json ']'//숫자 JSON 반환
반품 '{' . $json . '}'}
/**
* 임의의 문자열 생성
+------ ------------- ------------------------ ----
* @param int $length 생성할 랜덤 문자열의 길이
* @param string $type 랜덤 코드 유형: 0, 숫자 + 대문자 및 소문자 ;1, 숫자 2, 소문자; 3, 대문자 4, 특수 문자 -1, 숫자 + 대문자 및 소문자 + 특수 문자
+------------------------------- --------------
* @return string
+--------------- ------------------------------
*/
static public function randCode($length = 5 , $type = 2){
$arr = array(1 => "0123456789", 2=> "abcdefghijklmnopqrstuvw xyz", 3 => "ABCDEFGHIJKLMNOPQRSTUVWXYZ" , 4 => "~@#$%^&*(){}[]|");
if ($type == 0) {
array_pop($arr);
$string = implode("", $arr);
} elseif ($type == "-1") {
$string = 폭파("" , $arr);
} else {
$string = $arr[ $type];
}
$count = strlen($string) - 1;
$code = ''; ㅋㅋㅋ ++) {
$code .= $string[rand(0, $count)]; }
return $code;
}
/**
* GET 请求
* @param string $url
*/
비공개 기능 http_get($url){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt ($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
반품 $sContent;
}else{
return false;
}
}
/**
* POST 요청
* @param string $url
* @ param 배열 $param
* @param boolean $post_file 파일 업로드 여부?*/
비공개
기능 http_post($url,
,$post_file=false){ $oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($ oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (is_string ($param) || $post_file) {
$strPOST = $param;
} else {
$aPOST = array();
foreach($param as $key=>$val ){
$aPOST [] = $key."=".urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST,true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
반품 $sContent;
}else{
return false;
}
}
}
[php] 보기 plain복사
네임스페이스 WechatController;
use WechatControllerParentController;
/**
* WeChat 결제 테스트 컨트롤러
* @file TestController.class.php
* @author Gary
* @date 2015년 8월 4일
* @todu
*/
class TestController extends ParentController {
private $_order_body = 'xxx';
private $_order_goods_tag = 'xxx';
public function __construct(){
parent::__construct();
require_once ROOT_PATH."Api/lib/WxPay.Api.php";
require_once ROOT_PATH."Api/lib/WxPay.JsApiPay.php";
}
public functionindex(){
//①, 사용자 openid 가져오기
$tools = new JsApiPay();
$openId = $tools->GetOpenid()
//②、통합주문
$input = new WxPayUnifiedOrder()
$input-> $this
//추가 데이터, 필요한 데이터를 추가할 수 있습니다. WeChat은 비동기 콜백을 반환할 때 이 데이터를 추가합니다.
$input->SetAttach('xxx')
$out_trade_no = WxPayConfig::MCHID. date
(); $out_trade_no); //Total amount, 주문 총액은 정수만 가능하며 단위는 센트입니다.
$input->SetTotal_fee(1)
//거래 시작 시간
$input ->SetTime_start(날짜 (
))
$input->SetTime_expire(date("YmdHis", time() + 600))
//제품마크
$input->SetGoods_tag($this->_order_goods_tag)
//아니요 인증 주소, WeChat 결제 비동기 알림 수신 콜백 주소 SITE_URL = http : //test.paywechat.com/wharge
$ notify_url = index.php/test/notify.html';
$input$notify_url) $input
->$order = WxPayApi::unifiedOrder($input)
$jsApiParameters = $tools->GetJsApiParameters($ order);
//공유 배송 주소 js 함수 매개변수 가져오기
$editAddress = $ tools->GetEditAddressParameters() ; );
$this
'jsApiParameters',$jsApiParameters); , $editAddress )
$this->display()
}
API/lib/ inform.php";
$notify = new PayNotifyCallBack();
$not ify->핸들(false)
$is_success
=->IsSuccess();
$bdata = $is_success['data'];
if (
$is_success'code'] == 1){ $news =
array' touser' =>
$bdata'openid'], '뉴스',
'뉴스' = > 배열 (
'articles'=> 'title'
' 주문 결제가 완료되었습니다.',
'설명' => "결제 금액: {$bdata['total_fee']}n".
"WeChat 주문 번호: {$bdata['transaction_id']}n" 'picurl'
'',
'url' => ''
)
)//WeChat 결제 알림 보내기
$this->sendCustomMessage($news);
}else {//결제 실패
}
}
/**
* 결제 성공 페이지
* 신뢰할 수 없는 콜백
* //주문 번호
$out_trade_no = I('post.out_trade_no')
//결제금액
$total_fee = I('post.total_fee')
/*관련 논리 처리 ***
[xhtml]
>
meta http-equiv="content-type"content="text/html;charset=ut f- 8인치 ; ="width=device-width,initial-scale=1"
title> 위챗 결제 샘플 - 결제 title>
script type="text/javascript">
//WeChat JS API 결제 호출
functionjsApiCall()
{$jsApiParameters},
함수(res){
WeixinJSBridge.log(res.err_msg);
//취소 결제
if(res.err_ms g
여기에서 Ajax 제출을 사용하여 일부 로그를 처리할 수 있습니다. , 예를 들어 테스트 컨트롤러의 ajax_PaySuccess 메서드)
}
함수 callpay()
{
if (유형 WeixinJSBridge == "정의되지 않음"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}else{
jsApiCall();
}
}
//获取共享地址
함수 editAddress()
{
WeixinJSBridge. 호출(
'editAddress',
{$editAddress},
함수(res){
var value1 = res .proviceFirstStageName;
var value2 = res.addressCitySecondStageName;
var value3 = res.addressCountiesThirdStageName;
var value4 = res.addressDetailInfo;
var tel = res.telNumber;
alert(value1 + value2 + value3 + value4 + ":" + tel);
}
);
}
window.onload = function(){
if (유형은 WeixinJSBridge == "정의되지 않음"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', editAddress, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', editAddress);
document.attachEvent('onWeixinJSBridgeReady', editAddress);
}
}else{
editAddress();
}
};
script>
head>
body>
br/>
font color="#9ACD32">b> 이 주문의 결제 금액은 < ;spanstyle="color:#f00;font-size:50px">1포인트span> 돈 b> font> />
p align="center">
버튼 style= "너비:210px; 높이:50px; 테두리 반경: 15px;배경 색상:#FE6714; 테두리:0px #FE6714 단색; 커서: 포인터; 색상: 흰색; 글꼴 크기:16px;" type="버튼" onclick="callpay()" >立即支付 버튼>
p>
body>
html>
notify.php 파일 코드는 여기 공식 문서에 새롭게 추가된 커스텀 메소드가 있습니다.
[php] 보기 plain copy
require_onceROOT_PATH."Api/lib/WxPay.Api.php";
require_onceROOT_PATH .'Api/lib/WxPay.Notify.php' ;
//초기화 로그 CLogFileHandler(ROOT_PATH.
"/logs/"date( 'Y-m-d'). '.log') $logHandler , 15) {
protected $para = array('code'=>0,'data'=> '') ;
//查询订单
public function 쿼리순서( $transaction_id)
{
$input = new WxPayOrderQuery();
$input->SetTransaction_id($transaction_id);
$result = WxPayApi::orderQuery($input);
로그::DEBUG("query:" . json_encode($result));
if(array_key_exists("return_code", $result)
&& array_key_exists("result_code ", $result)
&& $result["return_code"] == "성공"
&& $result["result_code"] == "SUCCESS")
{
return 참;
}
$this->para['code'] = 0;
$this->para[ '데이터' ] = '';
return false;
//콜백 처리 함수 다시 작성
public function
NotifyProcess(, &$msg) { 로그: :DEBUG(
"콜백:"$data
)) ();
if(!array_key_exists("transaction_id", $data )){
$msg = "입력 매개변수가 잘못되었습니다."
$this->para['code'] = 0; $ this
'data'] = ''; return
//주문을 확인하고 주문의 진위 여부를 판단합니다
if(!$this->Queryorder($data["transaction_id"])){
$msg = "주문 쿼리 실패"
$this->para['code'] = 0; $이것
'data'] = ''; return
$this
->para[] = 1
$this->para['data'] = $data
사실
function IsSuccess(){
$this->para; 기본적으로 완료되었으며 WeChat에서 열 수 있습니다. http://test.paywechat.com/Charge/index.php/Test/index /
관련 추천:
WeChat 결제 기능의 nodejs 구현에 대한 자세한 설명
위 내용은 PHP는 WeChat 결제 기능 개발 코드 공유를 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!