API v2
Эта библиотека может быть использована отдельно для разработки APIv2. Она призвана обеспечить переход, позволяя сначала плавно перейти на эту библиотеку для взаимодействия с APIv2, а затем заменить её на APIv3 по мере необходимости.
V2 инициализация
use WeChatPay\Builder;
// 1. Пример использования:
$merchantId = '1000100'; // 商户号, предположительно 1000100
$apiv2Key = 'exposed_your_key_here_have_risks'; // APIv2 ключ (32 байта), замените на реальное значение
$merchantPrivateKeyFilePath = '/path/to/merchant/apiclient_key.pem'; // путь к файлу с приватным ключом
$merchantCertificateFilePath = '/path/to/merchant/apiclient_cert.pem'; // путь к файлу со свидетельством
// Создание экземпляра через фабричный метод:
$instance = Builder::factory([
'mchid' => $merchantId,
'serial' => 'nop',
'privateKey' => 'any',
'certs' => ['any' => null],
'secret' => $apiv2Key,
'merchant' => [
'cert' => $merchantCertificateFilePath,
'key' => $merchantPrivateKeyFilePath,
],
]);
Словарь инициализации:
mchid
— ваш номер продавца, обычно 10-значное число;serial
— серийный номер вашего сертификата, не используется в APIv3, можно заполнить любым значением;privateKey
— ваш API-ключ продавца, не используется в APIv3, можно заполнить любым значением;certs[$serial_number => #resource]
— не используется в APIv3, заполните любым значением, $serial_number
не должен совпадать с серийным номером сертификата serial
;secret
— ключ APIv2, установленный на платформе продавца как 32-байтовая строка;merchant[cert => $path]
— ваше свидетельство, обычно файл с именем apiclient_cert.pem
, принимает формат [$path, $passphrase]
, где $passphrase
— пароль сертификата;merchant[key => $path]
— ваш приватный ключ API, обычно это файл с именем apiclient_key.pem
, созданный официальным инструментом генерации сертификатов, принимает формат [$path, $passphrase]
, где $passphrase
— пароль ключа.Обратите внимание, что параметры инициализации для APIv3, APIv2 и GuzzleHttp\Client объединены в одном параметре типа.
Перевод средств на банковский счёт
Официальный документ разработчика: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
use WeChatPay\Transformer;
$res = $instance
->v2->mmpaymkttransfers->promotion->transfers
->postAsync([
'xml' => [
'mch_appid' => 'wx8888888888888888',
'mchid' => '1900000109', // обратите внимание на этот номер продавца, ключ — mchid, а не mch_id
'partner_trade_no' => '10000098201411111234567890',
'openid' => 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
'check_name' => 'FORCE_CHECK',
're_user_name' => '王小王',
'amount' => '10099',
'desc' => 'возмещение ущерба',
'spbill_create_ip' => '192.168.0.1',
],
'security' => true, // запрос требует двустороннего сертификата
'debug' => true // включить режим отладки
])
->then(static function($response) {
return Transformer::toArray((string)$response->getBody());
})
->otherwise(static function($e) {
// больше типов исключений $e необходимо проверить, здесь приведён только один возможный случай, пожалуйста, настройте и добавьте в соответствии с фактическим процессом подключения
if ($e instanceof \GuzzleHttp\Promise\RejectionException) {
return Transformer::toArray((string)$e->getReason()->getBody());
}
return [];
})
->wait();
print_r($res);
Параметры метода HTTP METHOD(POST)
для APIv2
включают два параметра, которые могут быть приняты массивом опций:
$options['nonceless']
— скалярное значение, которое означает, что в этом запросе не нужно автоматически добавлять параметр nonce_str
. Рекомендуется использовать логическое значение True
;$options['security']
— логическое значение True, означающее, что для этого запроса требуется загрузить SSL-сертификат, соответствующий структуре конфигурации array $config['merchant']
.Перевод средств на банковскую карту — получение открытого ключа RSA
Официальный документ разработчика: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_7&index=4
use WeChatPay\Transformer;
$res = $instance
->v2->risk->getpublickey
->postAsync([
'xml' => [
'mch_id' => '1900000109',
'sign_type' => 'MD5',
],
'security' => true, // требуется двусторонний сертификат
// специальный пункт доступа, действителен только для этого запроса
'base_uri' => 'https://fraud.mch.weixin.qq.com/',
])
->then(static function($response) {
return Transformer::toArray((string)$response->getBody());
})
->wait();
print_r($res);
Перевод средств на банковскую карту
Официальный документ разработчика: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_2
use WeChatPay\Transformer;
use WeChatPay\Crypto\Rsa;
// анонимный метод для последующего использования, $rsaPubKeyString — это возвращаемое значение 'pub_key' строки из risk/getpublickey
$rsaPublicKeyInstance = Rsa::from($rsaPubKeyString, Rsa::KEY_TYPE_PUBLIC);
$encryptor = static function(string $msg) use ($rsaPublicKeyInstance): string {
return Rsa::encrypt($msg, $rsaPublicKeyInstance);
};
$res = $instance
->v2->mmpaysptrans->pay_bank
->postAsync([
'xml' => [
'mch_id' => '1900000109',
'partner_trade_no' => '1212121221227',
'enc_bank_no' =>
``` Вызов встроенного метода SDK, выполнение локального расчёта подписи данных на основе [алгоритма подписи](https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3), затем сравнение с помощью Hash::equals с подписью sign в тексте уведомления;
4. Если сообщение необходимо расшифровать, то следует использовать встроенный метод SDK для расшифровки;
5. В случае возникновения проблем, пожалуйста, используйте Request-ID и перейдите [сюда](https://support.pay.weixin.qq.com/online-service?utm_source=github&utm_medium=wechatpay-php&utm_content=apiv2) для связи с официальной службой технической поддержки.
Пример кода:
```php
use WeChatPay\Transformer;
use WeChatPay\Crypto\Hash;
use WeChatPay\Crypto\AesEcb;
use WeChatPay\Formatter;
$inBody = '';// 请根据实际情况获取,例如: file_get_contents('php://input');
$apiv2Key = '';// 在商户平台上设置的APIv2密钥
$inBodyArray = Transformer::toArray($inBody);
// 部分通知体无`sign_type`,部分`sign_type`默认为`MD5`,部分`sign_type`默认为`HMAC-SHA256`
// 部分通知无`sign`字典
// 请根据官方开发文档确定
['sign_type' => $signType, 'sign' => $sign] = $inBodyArray;
$calculated = Hash::sign(
$signType ?? Hash::ALGO_MD5,// 如没获取到`sign_type`,假定默认为`MD5`
Formatter::queryStringLike(Formatter::ksort($inBodyArray)),
$apiv2Key
);
$signatureStatus = Hash::equals($calculated, $sign);
if ($signatureStatus) {
// 如需要解密的
['req_info' => $reqInfo] = $inBodyArray;
$inBodyReqInfoXml = AesEcb::decrypt($reqInfo, Hash::md5($apiv2Key));
$inBodyReqInfoArray = Transformer::toArray($inBodyReqInfoXml);
// print_r($inBodyReqInfoArray);// 打印解密后的结果
}
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.