تنفذ البرامج الوسيطة Guzzle HttpClient الخاصة بـ WeChat Payment API v3 إنشاء توقيعات الطلب والتحقق من توقيعات الاستجابة.
إذا كنت مطورًا تجاريًا يستخدم Guzzle، فيمكنك تمرير WechatPayGuzzleMiddleware
عند إنشاء GuzzleHttpClient
GuzzleHttpClient
الناتج معلومات مصادقة الهوية تلقائيًا عند تنفيذ الطلب، والتحقق من توقيع WeChat Pay للاستجابة.
الإصدار الحالي هو الإصدار التجريبي 0.2.0
. يرجى الانتباه إلى صحة وتوافق النظام والبرمجيات، فضلا عن المخاطر التي تنطوي عليها، عند استخدام الموظفين الفنيين والمهنيين لدى التاجر.
هذا المشروع قيد الصيانة . نوصي جميع المطورين بإعطاء الأولوية لاستخدام مكتبة تطوير PHP الجديدة الخاصة بـ WeChat Pay، wechatpay-php.
البيئة التي نستخدمها للتطوير والاختبار هي كما يلي:
ملاحظة: يمكن العثور على السبب المحدد لعدم دعم guzzle7 في المناقشة رقم 54. يرجى من المطورين الذين يعتمدون على guzzle7 استخدام wechatpay-php.
يمكنك استخدام مؤلف أداة إدارة حزم PHP لإدخال SDK في المشروع:
الطريقة الأولى: في دليل المشروع، أضف من خلال سطر أوامر الملحن:
composer require wechatpay/wechatpay-guzzle-middleware
الطريقة الثانية: أضف التكوين التالي إلى ملف Composer.json الخاص بالمشروع:
"require" : {
"wechatpay/wechatpay-guzzle-middleware" : " ^0.2.0 "
}
بعد إضافة التكوين، قم بإجراء التثبيت
composer install
أولاً، أنشئ WechatPayMiddleware
من خلال WechatPayMiddlewareBuilder
، ثم قم بإضافته إلى HandlerStack
الخاص بـ GuzzleHttpClient
. نحن نقدم طرقًا مناسبة لتمرير المعلومات بسهولة مثل المفاتيح الخاصة للتاجر وشهادات منصة الدفع WeChat.
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 );
عندما لا تكون أساليب التوقيع والتحقق المحلية الافتراضية مناسبة لنظامك، يمكنك تخصيص التوقيع والتحقق من خلال تنفيذ Signer
أو Verifier
. على سبيل المثال، إذا كان نظامك يقوم بتخزين مفاتيح التاجر الخاصة مركزيًا، وكان نظام الأعمال يحتاج إلى تنفيذ التوقيعات من خلال المكالمات عن بعد، فيمكنك القيام بذلك.
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 ();
يتطلب استخدام WechatPayMiddlewareBuilder
الاتصال withWechatpay
لتعيين شهادة منصة الدفع WeChat، ولا يمكن تنزيل شهادة النظام الأساسي إلا عن طريق الاتصال بـ Get Platform Certified API. من أجل كسر "الحلقة اللانهائية"، يمكنك "تخطي" التحقق من توقيع الاستجابة مؤقتًا عند تنزيل شهادة النظام الأساسي لأول مرة على النحو التالي.
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 ();
ملاحظة : يرجى استخدام عملية التهيئة القياسية لطلبات الأعمال، والتأكد من التحقق من توقيع الاستجابة.
يرجى الرجوع إلى AesUtil.php.
يوصى بالترقية إلى swoole 4.6+. تمت إضافة دعم swoole الأصلي (swoole/swoole-src#3863) في 4.6.0. لقد اختبرنا أنه يمكن استخدامه بشكل طبيعي. ولمزيد من التفصيل راجع رقم 36.
إذا وجدت خطأً أو كانت لديك أي أسئلة أو اقتراحات، فيرجى تقديم تعليقات عبر المشكلة.
مرحبا بكم أيضا في مجتمع المطورين لدينا.