Die Guzzle HttpClient-Middleware der WeChat Payment API v3 implementiert die Generierung von Anforderungssignaturen und die Überprüfung von Antwortsignaturen.
Wenn Sie ein Händlerentwickler sind, der Guzzle verwendet, können Sie WechatPayGuzzleMiddleware
beim Erstellen GuzzleHttpClient
übergeben. Die resultierende GuzzleHttpClient
Instanz überträgt automatisch Identitätsauthentifizierungsinformationen, wenn eine Anfrage ausgeführt wird, und überprüft die WeChat Pay-Signatur der Antwort.
Die aktuelle Version ist die Testversion 0.2.0
. Bitte achten Sie beim Einsatz des Fach- und Technikpersonals des Händlers auf die Korrektheit und Kompatibilität von System und Software sowie auf die damit verbundenen Risiken.
Dieses Projekt befindet sich in der Wartung . Wir empfehlen allen Entwicklern, die neue PHP-Entwicklungsbibliothek wechatpay-php von WeChat Pay zu verwenden.
Die Umgebung, die wir für Entwicklung und Tests verwenden, ist wie folgt:
Hinweis: Der konkrete Grund, warum guzzle7 nicht unterstützt wird, finden Sie in der Diskussion in #54. Entwickler, die auf guzzle7 angewiesen sind, verwenden bitte wechatpay-php.
Sie können das PHP-Paketverwaltungstool Composer verwenden, um das SDK in das Projekt einzuführen:
Methode 1: Fügen Sie im Projektverzeichnis über die Composer-Befehlszeile Folgendes hinzu:
composer require wechatpay/wechatpay-guzzle-middleware
Methode 2: Fügen Sie der Composer.json des Projekts die folgende Konfiguration hinzu:
"require" : {
"wechatpay/wechatpay-guzzle-middleware" : " ^0.2.0 "
}
Führen Sie nach dem Hinzufügen der Konfiguration die Installation durch
composer install
Erstellen Sie zunächst eine WechatPayMiddleware
über WechatPayMiddlewareBuilder
und fügen Sie sie dann HandlerStack
von GuzzleHttpClient
hinzu. Wir bieten entsprechende Methoden zur bequemen Weitergabe von Informationen wie privaten Händlerschlüsseln und Zertifikaten der WeChat-Zahlungsplattform.
use GuzzleHttp Exception RequestException ;
use WechatPay GuzzleMiddleware WechatPayMiddleware ;
use WechatPay GuzzleMiddleware Util PemUtil ;
// 商户相关配置
$ merchantId = ' 1000100 ' ; // 商户号
$ merchantSerialNumber = ' XXXXXXXXXX ' ; // 商户API证书序列号
$ merchantPrivateKey = PemUtil:: loadPrivateKey ( ' /path/to/mch/private/key.pem ' ); // 商户私钥
// 微信支付平台配置
$ wechatpayCertificate = PemUtil:: loadCertificate ( ' /path/to/wechatpay/cert.pem ' ); // 微信支付平台证书
// 构造一个WechatPayMiddleware
$ wechatpayMiddleware = WechatPayMiddleware:: builder ()
-> withMerchant ( $ merchantId , $ merchantSerialNumber , $ merchantPrivateKey ) // 传入商户相关配置
-> withWechatPay ([ $ wechatpayCertificate ]) // 可传入多个微信支付平台证书,参数类型为array
-> build ();
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$ stack = GuzzleHttp HandlerStack:: create ();
$ stack -> push ( $ wechatpayMiddleware , ' wechatpay ' );
// 创建Guzzle HTTP Client时,将HandlerStack传入
$ client = new GuzzleHttp Client ([ ' handler ' => $ stack ]);
// 接下来,正常使用Guzzle发起API请求,WechatPayMiddleware会自动地处理签名和验签
try {
$ resp = $ client -> request ( ' GET ' , ' https://api.mch.weixin.qq.com/v3/... ' , [ // 注意替换为实际URL
' headers ' => [ ' Accept ' => ' application/json ' ]
]);
echo $ resp -> getStatusCode (). ' ' . $ resp -> getReasonPhrase (). "n" ;
echo $ resp -> getBody (). "n" ;
$ resp = $ client -> request ( ' POST ' , ' https://api.mch.weixin.qq.com/v3/... ' , [
' json ' => [ // JSON请求体
' field1 ' => ' value1 ' ,
' field2 ' => ' value2 '
],
' headers ' => [ ' Accept ' => ' application/json ' ]
]);
echo $ resp -> getStatusCode (). ' ' . $ resp -> getReasonPhrase (). "n" ;
echo $ resp -> getBody (). "n" ;
} catch ( RequestException $ e ) {
// 进行错误处理
echo $ e -> getMessage (). "n" ;
if ( $ e -> hasResponse ()) {
echo $ e -> getResponse ()-> getStatusCode (). ' ' . $ e -> getResponse ()-> getReasonPhrase (). "n" ;
echo $ e -> getResponse ()-> getBody ();
}
return ;
}
// 参考上述指引说明,并引入 `MediaUtil` 正常初始化,无额外条件
use WechatPay GuzzleMiddleware Util MediaUtil ;
// 实例化一个媒体文件流,注意文件后缀名需符合接口要求
$ media = new MediaUtil ( ' /your/file/path/with.extension ' );
// 正常使用Guzzle发起API请求
try {
$ resp = $ client -> request ( ' POST ' , ' https://api.mch.weixin.qq.com/v3/[merchant/media/video_upload|marketing/favor/media/image-upload] ' , [
' body ' => $ media -> getStream (),
' headers ' => [
' Accept ' => ' application/json ' ,
' content-type ' => $ media -> getContentType (),
]
]);
// POST 语法糖
$ resp = $ client -> post ( ' merchant/media/upload ' , [
' body ' => $ media -> getStream (),
' headers ' => [
' Accept ' => ' application/json ' ,
' content-type ' => $ media -> getContentType (),
]
]);
echo $ resp -> getStatusCode (). ' ' . $ resp -> getReasonPhrase (). "n" ;
echo $ resp -> getBody (). "n" ;
} catch ( Exception $ e ) {
echo $ e -> getMessage (). "n" ;
if ( $ e -> hasResponse ()) {
echo $ e -> getResponse ()-> getStatusCode (). ' ' . $ e -> getResponse ()-> getReasonPhrase (). "n" ;
echo $ e -> getResponse ()-> getBody ();
}
return ;
}
// 参考上上述说明,引入 `SensitiveInfoCrypto`
use WechatPay GuzzleMiddleware Util SensitiveInfoCrypto ;
// 上行加密API 多于 下行解密,默认为加密,实例后直接当方法用即可
$ encryptor = new SensitiveInfoCrypto (PemUtil:: loadCertificate ( ' /path/to/wechatpay/cert.pem ' ));
// 正常使用Guzzle发起API请求
try {
// POST 语法糖
$ resp = $ client -> post ( ' /v3/applyment4sub/applyment/ ' , [
' json ' => [
' business_code ' => ' APL_98761234 ' ,
' contact_info ' => [
' contact_name ' => $ encryptor ( ' value of `contact_name` ' ),
' contact_id_number ' => $ encryptor ( ' value of `contact_id_number ' ),
' mobile_phone ' => $ encryptor ( ' value of `mobile_phone` ' ),
' contact_email ' => $ encryptor ( ' value of `contact_email` ' ),
],
//...
],
' headers ' => [
// 命令行获取证书序列号
// openssl x509 -in /path/to/wechatpay/cert.pem -noout -serial | awk -F= '{print $2}'
// 或者使用工具类获取证书序列号 `PemUtil::parseCertificateSerialNo($certificate)`
' Wechatpay-Serial ' => ' must be the serial number via the downloaded pem file of `/v3/certificates` ' ,
' Accept ' => ' application/json ' ,
],
]);
echo $ resp -> getStatusCode (). ' ' . $ resp -> getReasonPhrase (). "n" ;
echo $ resp -> getBody (). "n" ;
} catch ( Exception $ e ) {
echo $ e -> getMessage (). "n" ;
if ( $ e -> hasResponse ()) {
echo $ e -> getResponse ()-> getStatusCode (). ' ' . $ e -> getResponse ()-> getReasonPhrase (). "n" ;
echo $ e -> getResponse ()-> getBody ();
}
return ;
}
// 单例加解密示例如下
$ crypto = new SensitiveInfoCrypto ( $ wechatpayCertificate , $ merchantPrivateKey );
$ encrypted = $ crypto ( ' Alice ' );
$ decrypted = $ crypto -> setStage ( ' decrypt ' )( $ encrypted );
Wenn die standardmäßigen lokalen Signatur- und Verifizierungsmethoden für Ihr System nicht geeignet sind, können Sie die Signierung und Verifizierung durch die Implementierung Signer
oder Verifier
anpassen. Wenn Ihr System beispielsweise private Händlerschlüssel zentral speichert und das Geschäftssystem Signaturen über Remote-Aufrufe durchführen muss, können Sie dies tun.
use WechatPay GuzzleMiddleware Auth Signer ;
use WechatPay GuzzleMiddleware Auth SignatureResult ;
use WechatPay GuzzleMiddleware Auth WechatPay2Credentials ;
class CustomSigner implements Signer
{
public function sign ( $ message )
{
// 调用签名RPC服务,然后返回包含签名和证书序列号的SignatureResult
return new SignatureResult ( ' xxxx ' , ' yyyyy ' );
}
}
$ credentials = new WechatPay2Credentials ( $ merchantId , new CustomSigner );
$ wechatpayMiddleware = WechatPayMiddleware:: builder ()
-> withCredentials ( $ credentials )
-> withWechatPay ([ $ wechatpayCertificate ])
-> build ();
Für die Verwendung WechatPayMiddlewareBuilder
ist ein Aufruf von withWechatpay
erforderlich, um das WeChat-Zahlungsplattformzertifikat festzulegen. Das Plattformzertifikat kann nur durch Aufrufen der Get Platform Certificate-API heruntergeladen werden. Um die „Endlosschleife“ zu durchbrechen, können Sie die Überprüfung der Antwortsignatur beim ersten Download des Plattformzertifikats wie folgt vorübergehend „überspringen“.
use WechatPay GuzzleMiddleware Validator ;
class NoopValidator implements Validator
{
public function validate ( Psr Http Message ResponseInterface $ response )
{
return true ;
}
}
$ wechatpayMiddleware = WechatPayMiddleware:: builder ()
-> withMerchant ( $ merchantId , $ merchantSerialNumber , $ merchantPrivateKey )
-> withValidator ( new NoopValidator ) // NOTE: 设置一个空的应答签名验证器,**不要**用在业务请求
-> build ();
Hinweis : Bitte verwenden Sie den Standardinitialisierungsprozess für Geschäftsanfragen und überprüfen Sie unbedingt die Antwortsignatur.
Bitte beachten Sie AesUtil.php.
Es wird empfohlen, ein Upgrade auf swoole 4.6+ durchzuführen. In 4.6.0 wurde die Unterstützung für natives Curl (swoole/swoole-src#3863) hinzugefügt. Wir haben getestet, dass es normal verwendet werden kann. Nähere Informationen finden Sie unter Nr. 36.
Wenn Sie einen Fehler finden oder Fragen oder Vorschläge haben, geben Sie uns bitte Feedback über das Problem.
Willkommen auch in unserer Entwickler-Community.