Dieser Artikel stellt hauptsächlich den Entwicklungsprozess der PHP-WeChat-Zahlung im Detail vor. Interessierte Freunde können darauf verweisen.
1. Entwicklungsumgebung
Thinkphp 3.2.3
WeChat: Dienstkonto, zertifiziert
Entwicklungsdomänenname: http://test.paywechat.com (seit Auf den definierten Domänennamen kann nicht über das externe Netzwerk zugegriffen werden)
2. Relevante Dokumente und Berechtigungen sind erforderlich
WeChat-Zahlung muss aktiviert werden
Entwicklerdokumentation für die öffentliche WeChat-Plattform: http:// mp.weixin.qq.com/wiki/home/index.html
WeChat Payment Developer Documentation: https://pay.weixin.qq.com/wiki/doc/api/index.html
WeChat Payment SDK-Downloadadresse: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
Entwicklung
Laden Sie die WeChat Payment PHP-Version des SDK herunter. Das Dateiverzeichnis ist wie folgt:
Legen Sie die Cert- und Lib-Verzeichnisse ab Das Verzeichnis des WeChat-Zahlungs-SDK Thinkphp lautet
Nun stellen wir das Problem mit dem WeChat-Zahlungsautorisierungsverzeichnis vor. Das erste besteht darin, die Zahlungsautorisierung auszufüllen Verzeichnis in der WeChat-Zahlungsentwicklungskonfiguration,
Füllen Sie dann die Sicherheitsdomäne der js-Schnittstelle aus.
Stellen Sie abschließend die Web-Autorisierung ein
Nachdem diese Einstellungen abgeschlossen sind, ist es im Grunde schon zur Hälfte erledigt.
4. WeChat-Zahlungskonfiguration
Füllen Sie die entsprechende Konfiguration korrekt aus .
[php] Ansicht schlichtKopie
/**
* Kontoinformationen konfigurieren
*/
Klasse WxPayConfig
{
//========[Grundlegende Informationseinstellungen]=================== = =================
//
/**
* TODO: Ändern Sie die Konfiguration hier, um Ihre eigenen Händlerinformationen zu beantragen
* Öffentliche WeChat-Kontoinformationen Konfiguration
*
* APPID : An die Zahlung gebundene APPID (muss konfiguriert werden, kann in der Kontoeröffnungs-E-Mail eingesehen werden)
*
* MCHID: Händler-ID (muss konfiguriert werden, kann in der Kontoeröffnungs-E-Mail eingesehen werden)
* )
* Adresse einstellen: https://pay.weixin .qq.com/index.php/account/api_cert
*
* APPSECRET: Öffentliches Kontogeheimnis (nur für JSAPI-Zahlung erforderlich, melden Sie sich bei der öffentlichen Plattform an und betreten Sie das Entwicklercenter, um es festzulegen),
* Adresse erhalten: https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @var string
*/
const APPID = '' ; >;
const KEY = '' ;
const APPSECRET = ''; ===【Zertifikatpfadeinstellungen】=====================================
/**
* TODO: Händlerzertifikatpfad festlegen
* Download-Adresse des API-Zertifikats: https://pay.weixin.qq.com/index.php/account/api_cert, Sie müssen vorher das Händlerbetriebszertifikat installieren Herunterladen)
* @var path
*/
const SSLCERT_PATH = './cert/apiclient_cert.pem''../cert/apiclient_key.pem'; 🎜>//========[Curl-Proxy-Einstellungen]======================= ========= ===
/**
* TODO: Stellen Sie die Proxy-Maschine hier nur ein, wenn Sie keinen Proxy benötigen , bitte setzen Sie es auf 0.0.0.0 und 0
* Diese Routine verwendet die HTTP-POST-Methode über Curl Der Proxyserver kann sein hier geändert,
* Standardmäßig CURL_PROXY_HOST=0.0.0.0 und CURL_PROXY_PORT=0, der Proxy ist derzeit nicht aktiviert (einstellen). ggf.)
* @var unlimited_type
*/
const CURL_PROXY_HOST = "0.0.0.0";// "10.152.18.220";
const CURL_PROXY_PORT = 0; //8080;
//========【Konfiguration der Berichtsinformationen】============================= ==== ====
/**
* TODO: Berichtsebene für Schnittstellenaufrufe, standardmäßige Fehlerberichterstattung (Hinweis: Berichtszeitüberschreitung beträgt [1s], Berichterstattung unabhängig vom Erfolg oder Fehler [Niemals eine Ausnahme auslösen],
* hat keinen Einfluss auf den Schnittstellenaufrufprozess), nachdem die Berichterstellung aktiviert wurde Praktisch für WeChat-Überwachungsanfrageanrufe. Aus Qualitätsgründen wird empfohlen, mindestens
* die Fehlerberichterstattung einzuschalten.
* Meldeebene, 0. Schließen Sie die Meldung; 1. Es werden nur Fehler gemeldet.
* @var int
*/
const REPORT_LEVENL = 1;
}
Beginnen Sie jetzt mit der Veröffentlichung des Codes:
[php]Ansicht plain copy
Namespace WechatController;
verwendenThinkController; >/**
* Der Controller der übergeordneten Klasse muss erben
* @file ParentController.class.php
* @author Gary
* @date 4. August 2015
* @todu
*/
Klasse ParentController erweitert Controller {
protected $options = array (
'token' => '', // Geben Sie den von Ihnen festgelegten Schlüssel ein
'encodingaeskey' => '', // Geben Sie den EncodingAESKey für die Verschlüsselung ein
'appid' => '', // Füllen in advanced Die App-ID der aufrufenden Funktion
'appsecret' => ; '', // Geben Sie den Schlüssel für die erweiterte Anruffunktion ein
'debug' => falsch,
'logcallback' => ''
);
public $errCode = 40001;
public $errMsg = „Kein Zugriff“;
/**
* 获取access_token
* @return mixed|boolean|unknown
*/
öffentliche Funktion getToken(){
$cache_token = S('exp_wechat_pay_token');
if(!leer( $cache_token)){
return $cache_token;
}
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
$url = sprintf($url, $this->options['appid'],$this ->options['appsecret']);
$result = $this->http_get($ URL);
$result = json_decode($result, WAHR);
if(leer($result)){
return false;
}
S('exp_wechat_pay_token',$result['access_token'],Array ('type'=>'file','expire' =>3600));
return $result['access_token'];
}
/**
* Kundendienstnachricht senden
* @param array $data Nachrichtenstruktur {"touser": "OPENID", "msgtype": "news", "news":{...}🎜>
*/
öffentlich Funktion sendCustomMessage($data){
$token = $this->getToken();
if (leer($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);
if (!$json || !empty($json['errcode'])) {
$this->errCode = $json['errcode' ];
$this->errMsg = $json['errmsg'];
return false;
}
zurück $json;
}
zurück FALSCH;
}
/**
* Vorlagenachricht senden
* @param unlimited $data
* @return boolean|unknown
*/
öffentlich Funktion sendTemplateMessage($data){
$token = $this->getToken();
if (leer($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);
if (!$json || !empty($json['errcode'])) {
$this->errCode = $json['errcode' ];
$this->errMsg = $json['errmsg'];
return false;
}
zurück $json;
}
zurück FALSCH;
}
public function getFileCache($name){
return S($name);
}
/**
* Die WeChat-API unterstützt keine chinesische Escape-JSON-Struktur
* @param array $arr
*/
statisch Funktion json_encode($arr) {
$parts = array ();
$is_list = false;
//Finden Sie heraus, ob das gegebene Array ein numerisches Array ist
$keys = array_keys ( $arr );
$max_length = count ( $arr ) - 1;
if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //Überprüfen Sie, ob der erste Schlüssel 0 ist und der letzte Schlüssel die Länge 1 hat.
$is_list = true;
für($i = 0; $i count ( $keys ); $i ++) { //Überprüfen, ob jede Taste ihrer Position entspricht
if ($i != $keys [$i ]) { //Eine Taste schlägt bei der Positionsprüfung fehl.
$is_list = false; //Es ist ein assoziatives Array.
Pause;
}
}
}
foreach ( $arr as $key => $value ) {
if (is_array ( $value )) { //Benutzerdefinierte Behandlung für Arrays
if ($is_list)
$parts [] = self::json_encode ( $value ); /* :RECURSION: */
else
$parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */
} else {
$str = '';
if (! $is_list)
$str = '"' . $key . '":';
//Benutzerdefinierte Behandlung für mehrere Datentypen
if (!is_string ( $value ) && is_numeric ( $value ) && $value
$str .= $value ; //Zahlen
elseif ( $value === false)
$str .= 'false'; //Die booleschen Werte
elseif ($value === true)
$str . = 'wahr';
else
$str .= '"' . fügt Schrägstriche hinzu ( $value ) . '"'; //Alle anderen Dinge
// :TODO: Gibt es noch mehr Datentyp, nach dem wir Ausschau halten sollten? (Objekt?)
$parts [] = $str;
}
}
$json = implode ( ',', $parts );
if ($is_list)
return '[' .$json . ']' > zurück'{'
.} > +--------------------------------- ------- ---------------------
* Zufällige Zeichenfolge generieren
+---------------------------------- ------------------------
* @ Rückgabezeichenfolge
+----------------------- -----------------------------------
*/
statisch public function randCode($length = 5, $ Typ = 2){
$arr = array(1 => "0123456789", 2 => "abcdefghijklmnopqrstuvwxyz", 3 = > "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 4 => "~@#$%^&*(){}[]|");
if ($type == 0) {
array_pop($arr);
$string = implode("", $arr);
} elseif ($type == "-1") {
$string = implode("", $arr);
} else {
$string = $arr[$type];
}
$count = strlen($string) - 1;
$code = '';
für ($i = 0; $i $length; $i++) {
$code .= $string[rand(0 , $count)];
}
zurück $code;
}
/**
* GET 请求
* @param string $url
*/
privat Funktion 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){
return $sContent;
}else{
return false;
}
}
/**
* POST-Anfrage
* @param string $url
* @param array $param
* @param boolean $post_file Ob Dateien hochgeladen werden sollen
* @return string content
*/
privat Funktion http_post($url,$param,$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;
} sonst {
$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){
return $sContent;
}else{
return false;
}
}
}
[php] ansehen plain copy
Namespace WechatController;
verwenden WechatControllerParentController;
/**
* WeChat-Zahlungstestcontroller
* @file TestController.class.php
* @author Gary
* @date 4. August 2015
* @todu
*/
Klasse TestController erweitert ParentController {
privat $_order_body = 'xxx';
privat $_order_goods_tag = 'xxx';
öffentlich Funktion __construct(){
parent::__construct();
require_once ROOT_PATH."Api/lib/WxPay.Api.php" ;
require_once ROOT_PATH."Api/lib/WxPay.JsApiPay.php" ;
}
public function index(){
///①, Benutzer-OpenID abrufen
$tools = neu JsApiPay();
$openId = $tools->GetOpenid(); > //②, Einheitliche Reihenfolge
$input
=WxPayUnifiedOrder(); > $input
->SetBody(- >_order_body);
$input->SetAttach('xxx');
//Händlerbestellnummer
$out_trade_no = WxPayConfig::MCHID.Datum("YmdHis"); 🎜>
$input->SetOut_trade_no($out_trade_no ; 🎜>
$input->SetTotal_fee(1);
//Transaktionsstartzeit
$ Eingabe->SetTime_start(Datum(
)); //Endzeit der Transaktion
$input->SetTime_expire(date("YmdHis ", time() + 600));
//Produkt-Tag
$input->SetGoods_tag($this->_order_goods_tag);
//Benachrichtigungsadresse, Rückrufadresse für asynchrone WeChat-Zahlung erhalten SITE_URL=http://test .paywechat.com/Charge
$notify_url = SITE_URL. '/index.php/Test/notify.html'->SetNotify_url($notify_url
/ /Handelstyp
$input->SetTrade_type("JSAPI"
);) ;
$order = WxPayApi::unifiedOrder($input);
$jsApiParameters = $tools->GetJsApiParameters( $order);
//Erhalten Sie die js-Funktionsparameter für die gemeinsame Lieferadresse
$editAddress = $tools ->GetEditAddressParameters();
this
->assign(,$openId); $this
->assign(, $jsApiParameters); 'editAddress' ,$editAddress);
$this->display(); > }
/**
* Asynchrone Benachrichtigungsrückrufmethode
*/
öffentlich
notify (){ require_once
ROOT_PATH.; > PayNotifyCallBack();
$notify- >Handle(false); >
= $notify ->IsSuccess();
$bdata = $is_success['data'];
//支付成功
if($is_success['code'] == 1 ){
$news = array(
'touser' => $bdata[ 'openid'],
'msgtype' => 'news',
'news' => Array (
'articles'=> array (
array(
'title' => 'Bestellung erfolgreich bezahlt', >'Beschreibung' => {$bdata['total_fee']}n"
"WeChat-Bestellnummer: {$bdata['transaction_id']}n"
=> '',
'url' =>''
)
)
) ;
//WeChat-Zahlungsbenachrichtigung senden
$this->sendCustomMessage($news); > }else
{}
/**
* Zahlungserfolgsseite
* Unzuverlässige Rückrufe
*/
Funktion ajax_PaySuccess(){
//Bestellnummer
= I('post.out_trade_no');
//Zahlungsbetrag total_fee = I(
); /*Verwandte Logikverarbeitung*/
html
Kopf
meta http-equiv="content-type" content="text/html;charset=utf-8" />
meta name="viewport" content="width= device-width, initial-scale=1"/>
< ;title>微信支付样例-支付title >
Skript Typ= „Text/Javascript“>
//WeChat JS API-Zahlung aufrufen
Funktion jsApiCall()
{
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
{$jsApiParameters},
function(res){
WeixinJSBridge.log( res.err_msg);
//Zahlung abbrechen
if( res.err_msg == 'get_brand_wcpay_request:cancel'){
//Ereignislogik zur Verarbeitung der Zahlungsstornierung
}else if(res.err_msg == "get_brand_wcpay_request: ok"){
/*Verwenden Sie die obige Methode, um die Front-End-Rendite zu ermitteln. Das WeChat-Team erinnert feierlich daran:
res .err_msg wird verwendet, wenn der Benutzer nach Erfolg eine Rückgabe in Ordnung macht, aber es garantiert nicht, dass es absolut zuverlässig ist
Hier können Sie Ajax zum Senden verwenden den Hintergrund und verarbeiten Sie einige Protokolle, z. B. ajax_PaySuccess in der Test-Controller-Methode. err_code+res.err_desc+res.err_msg); 🎜>
}
Funktion callpay()
{
if (typeof WeixinJSBridge == "undefiniert"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if (document.attachEvent){
document.attachEvent(' WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}else{
jsApiCall();
}
}
//获取共享地址
function editAddress()
{
WeixinJSBridge.invoke(
'editAddress',
{$editAddress},
function(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 (typeof WeixinJSBridge == "undefiniert"){
if( document. addEventListener ){
document.addEventListener('WeixinJSBridgeReady', editAddress, false);
}else if (document.attachEvent){
document.attachEvent(' WeixinJSBridgeReady', editAddress);
document.attachEvent('onWeixinJSBridgeReady', editAddress);
}
}else{
editAddress();
}
};
Skript>
Kopf >
Körper >
br/>
Schriftart Farbe= „#9ACD32“>b>Der Zahlungsbetrag für diese Bestellung beträgt span style="color:#f00;font-size:50px " >1 PunktSpanne>Geld b>Schriftart>br/>br/>
p align= „Mitte“>
Schaltfläche Stil="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border: 0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" ="button" onclick="callpay()" >立即支付Schaltfläche>
p>
Körper>
html>
notify.php-Dateicode, hier ist eine neu hinzugefügte benutzerdefinierte Methode in der offiziellen Datei.
[php] Ansicht einfachkopieren
require_onceROOT_PATH."Api/lib/WxPay.Api.php"; >require_once
ROOT_PATH.; require_once
ROOT_PATH.;
//初始化日志
$logHandler= neu CLogFileHandler(ROOT_PATH." /logs/".Datum('Y-m-d'). '.log');
$log = Log::Init($logHandler, 15);
Klasse PayNotifyCallBack verlängert WxPayNotify
{
geschützt $para = Array ('code'=>0,'data'=>'' );
//查询订单
public function Queryorder($transaction_id)
{
$input = neu WxPayOrderQuery();
$input->SetTransaction_id($transaction_id);
$result = WxPayApi::orderQuery($input);
Log::DEBUG("query:" . json_encode($result));
if(array_key_exists("return_code", $result)
&& array_key_exists("result_code", $result)
&& $result["return_code"] == " ERFOLGREICH"
&& $result["result_code "] == "ERFOLG")
{
return true;
}
$this->para['code'] = 0;
$this->para['data'] = '';
return false
// Schreiben Sie die Callback-Handler-Funktion neu
public Funktion NotifyProcess($data, &$msg)
"call zurück: „ .json_encode($data));
$notfiyOutput = array();
if(!array_key_exists("transaction_id", $data)){
$msg = "Die Eingabeparameter sind falsch"; >
->para['code'] = 0; >
->para['data' ] = '';
false;
}
if(!$this->Queryorder($ Daten["transaction_id"])){
$msg = "Bestellabfrage fehlgeschlagen";
$this->para['code'] = 0;
$this->para['data'] = '';
return false; > }
$this
'code'] = 1;
$this->para['data'] = $data; 🎜>
/**
* Benutzerdefinierte Methode zur Erkennung, ob der Rückruf auf WeChat erfolgreich ist
* @return multitype:number string
*/
Funktion IsSuccess(){
return $this->para;
}Dies ist im Grunde genommen abgeschlossen, Sie können http://test.paywechat auf WeChat com/Charge/index.php/Test/index/Related öffnen Empfehlungen:
Detaillierte Erläuterung der NodeJS-Implementierung des WeChat-Zahlungsfunktionsbeispiels
Thinkphp integriert die WeChat-Zahlungsfunktion
So fügen Sie diese WeChat-Zahlungsfunktion zur PC-Website hinzu
Das obige ist der detaillierte Inhalt vonPHP implementiert die Codefreigabe für die WeChat-Zahlungsfunktionsentwicklung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!