diff --git a/src/Pay/Client.php b/src/Pay/Client.php index 61e54fcaa..633db93bd 100644 --- a/src/Pay/Client.php +++ b/src/Pay/Client.php @@ -145,6 +145,11 @@ public function request(string $method, string $url, array $options = []): Respo if (! empty($this->prependHeaders)) { $options['headers'] = array_merge($this->prependHeaders, $options['headers']); } + + //如果有加密字段,需要携带 + if(! isset($options['headers']['Wechatpay-Serial']) && $serial = $this->merchant->getPlatformCertSerial()){ + $options['headers']['Wechatpay-Serial'] = $serial; + } return new Response( $this->client->request($method, $url, $options), diff --git a/src/Pay/Contracts/Merchant.php b/src/Pay/Contracts/Merchant.php index 0e2bc440a..ada407231 100644 --- a/src/Pay/Contracts/Merchant.php +++ b/src/Pay/Contracts/Merchant.php @@ -25,4 +25,8 @@ public function getPlatformCert(string $serial): ?PublicKey; * @return PublicKey[] */ public function getPlatformCerts(): array; + + public function getPlatformCertSerial(): ?string; + + public function setPlatformCertSerial(string $serial): static; } diff --git a/src/Pay/Merchant.php b/src/Pay/Merchant.php index 1da21300d..3d9a6fab8 100644 --- a/src/Pay/Merchant.php +++ b/src/Pay/Merchant.php @@ -21,6 +21,11 @@ class Merchant implements MerchantInterface */ protected array $platformCerts = []; + /** + * @var string|null + */ + protected ?string $platCertSerial = null; + /** * @param array $platformCerts * @@ -63,6 +68,11 @@ public function getV2SecretKey(): ?string return $this->v2SecretKey; } + public function getPlatformCertSerial(): ?string + { + return $this->platCertSerial; + } + public function getPlatformCert(string $serial): ?PublicKey { return $this->platformCerts[$serial] ?? null; @@ -98,4 +108,11 @@ protected function normalizePlatformCerts(array $platformCerts): array return $certs; } + + public function setPlatformCertSerial(string $serial): static + { + $this->platCertSerial = $serial; + + return $this; + } } diff --git a/src/Pay/Utils.php b/src/Pay/Utils.php index ffd2f0f36..b9b662a04 100644 --- a/src/Pay/Utils.php +++ b/src/Pay/Utils.php @@ -168,8 +168,10 @@ protected function createSignature(string $message): string */ public function createRsaEncrypt(string $plaintext, ?string $serial = null): string { + $serial = $serial ?? $this->merchant->getPlatformCertSerial(); $platformCerts = $this->merchant->getPlatformCerts(); $platformCert = $serial ? $this->merchant->getPlatformCert($serial) : reset($platformCerts); + if (empty($platformCert)) { throw new InvalidConfigException('Missing platform certificate.'); } @@ -177,6 +179,8 @@ public function createRsaEncrypt(string $plaintext, ?string $serial = null): str if (!openssl_public_encrypt($plaintext, $encrypted, $platformCert, OPENSSL_PKCS1_OAEP_PADDING)) { throw new EncryptionFailureException('Encrypt failed.'); } + + $this->merchant->setPlatformCertSerial($serial ?? key($platformCerts)); return base64_encode($encrypted); } diff --git a/tests/Pay/UtilsTest.php b/tests/Pay/UtilsTest.php index 7b9bdf9ec..2ab5034d3 100644 --- a/tests/Pay/UtilsTest.php +++ b/tests/Pay/UtilsTest.php @@ -81,12 +81,18 @@ public function test_create_rsa_encrypt() ] ); $utils = new Utils(merchant: $merchant); + $this->assertSame(null,$merchant->getPlatformCertSerial()); $this->assertIsString($utils->createRsaEncrypt('mock-plaintext', 'PUB_KEY_ID_123456')); + $this->assertSame('PUB_KEY_ID_123456',$merchant->getPlatformCertSerial()); + $this->assertIsString($utils->createRsaEncrypt('mock-plaintext')); + $this->assertSame('PUB_KEY_ID_123456',$merchant->getPlatformCertSerial()); + $this->expectException(InvalidConfigException::class); $utils->createRsaEncrypt('mock-plaintext', 'PUB_KEY_ID_456789'); - $this->expectException(EncryptionFailureException::class); - $utils->createRsaEncrypt('', 'PUB_KEY_ID_123456'); - + + $this->expectException(EncryptionFailureException::class); + $utils->createRsaEncrypt(str_repeat('A', 256), 'PUB_KEY_ID_123456'); + } }