PayPlusServiceTest.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace Tests\Unit;
  3. use App\Services\PayPlus;
  4. use Tests\TestCase;
  5. class PayPlusServiceTest extends TestCase
  6. {
  7. /** @test */
  8. public function it_builds_payout_sign_with_flattened_sorted_payload()
  9. {
  10. $service = new PayPlus([
  11. 'appKey' => '123456',
  12. ]);
  13. $payload = [
  14. 'k2' => [1, 2],
  15. 'empty' => '',
  16. 'k3' => [
  17. 'b1' => 'test1',
  18. 'a2' => 'test2',
  19. ],
  20. 'k1' => 1,
  21. 'null_value' => null,
  22. ];
  23. $sign = $service->signPayoutPayload($payload);
  24. $this->assertSame(
  25. hash('sha256', 'k1=1&k2=[1,2]&k3_a2=test2&k3_b1=test1' . '123456'),
  26. $sign
  27. );
  28. }
  29. /** @test */
  30. public function it_formats_payout_notify_amounts_to_four_decimals_when_verifying_signature()
  31. {
  32. $service = new PayPlus([
  33. 'appKey' => '123456',
  34. ]);
  35. $payload = [
  36. 'transaction_id' => 'T100',
  37. 'reference_id' => 'TX100',
  38. 'status' => 'PAID',
  39. 'timestamp' => 162856465000,
  40. 'payout_amount' => 10,
  41. 'source_amount' => '11',
  42. 'payout_fee' => 1,
  43. ];
  44. $signString = 'payout_amount=10.0000&payout_fee=1.0000&reference_id=TX100'
  45. . '&source_amount=11.0000&status=PAID&timestamp=162856465000&transaction_id=T100';
  46. $this->assertTrue($service->verifyPayoutSignature(
  47. $payload,
  48. hash('sha256', $signString . '123456')
  49. ));
  50. }
  51. /** @test */
  52. public function it_encrypts_and_decrypts_component_delta_with_aes_gcm()
  53. {
  54. $service = new PayPlus([]);
  55. $aesKey = str_repeat('01', 32);
  56. $iv = str_repeat('02', 12);
  57. $payload = '{"hello":"payplus"}';
  58. $encrypted = $service->encryptComponentDelta($payload, $aesKey, $iv);
  59. $decrypted = $service->decryptComponentDelta($encrypted, $aesKey, $iv);
  60. $this->assertSame($payload, $decrypted);
  61. }
  62. /** @test */
  63. public function it_encrypts_payin_payload_with_native_rsa_oaep_sha512()
  64. {
  65. $service = new PayPlus([
  66. 'publicKey' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnuDnY8u7a9EvUBAG7jJd'
  67. . 'KNkPS2vPpHo/gp7f2TA62cHXRW0AmeqHoWkcW6s8mMyP9EC6zNOcaVbPZrh6o9q0'
  68. . 'X06eZadexSK8bBY24c1j+uR1mivRcyB8bPiaNMGLaKKXpkbwttP+No7AOpAkWXx3'
  69. . 'pemXJeO8CRZGGRT79gv4v8Sd9KXJvsV4tdOU/RObMBtjtyWnGbNWWkxyJfq/sU4e'
  70. . 'DnFUr9J3jc1U6pPty/6ziukt6dMXth5qaod8kf7QMI0gXMlIi9znTLLSsQUzcZA0'
  71. . 'pB4/QvEExJxq0mtCtrq80UWITeE0frgbS4djq9XFGU+YlEXEX9DWgby5E9uX05vV'
  72. . 'UQIDAQAB',
  73. ]);
  74. $encrypted = $service->encryptPayinPayload([
  75. 'platform_order_id' => 'P100',
  76. 'amount' => '10.00',
  77. ]);
  78. $this->assertSame(64, strlen($encrypted['aes_key']));
  79. $this->assertSame(24, strlen($encrypted['iv']));
  80. $this->assertSame(344, strlen($encrypted['body']['componentX']));
  81. $this->assertSame(344, strlen($encrypted['body']['componentY']));
  82. $this->assertNotEmpty($encrypted['body']['componentDelta']);
  83. }
  84. /** @test */
  85. public function it_builds_beneficiary_payload_with_safe_defaults()
  86. {
  87. $service = new PayPlus([]);
  88. $payload = $service->buildBeneficiaryPayload([
  89. 'user_id' => 10001,
  90. 'email' => '',
  91. 'phone' => '',
  92. 'first_name' => '',
  93. 'last_name' => '',
  94. ], 1234567890);
  95. $this->assertSame('10001', $payload['payee_id']);
  96. $this->assertSame('en', $payload['language']);
  97. $this->assertSame('US', $payload['country']);
  98. $this->assertSame('+1-0000000000', $payload['phone']);
  99. $this->assertSame('unknown10001@example.com', $payload['email']);
  100. $this->assertSame('unknown', $payload['first_name']);
  101. $this->assertSame('user', $payload['last_name']);
  102. $this->assertSame(1234567890, $payload['timestamp']);
  103. }
  104. /** @test */
  105. public function it_keeps_only_english_letters_for_beneficiary_names()
  106. {
  107. $service = new PayPlus([]);
  108. $payload = $service->buildBeneficiaryPayload([
  109. 'user_id' => 10002,
  110. 'first_name' => '张San-123',
  111. 'last_name' => '李User_456',
  112. ], 1234567890);
  113. $this->assertSame('San', $payload['first_name']);
  114. $this->assertSame('User', $payload['last_name']);
  115. $payload = $service->buildBeneficiaryPayload([
  116. 'user_id' => 10003,
  117. 'first_name' => '张三123',
  118. 'last_name' => '456-',
  119. ], 1234567890);
  120. $this->assertSame('unknown', $payload['first_name']);
  121. $this->assertSame('user', $payload['last_name']);
  122. }
  123. }