Skip to content

Commit

Permalink
Void
Browse files Browse the repository at this point in the history
  • Loading branch information
recca0120 committed Nov 12, 2023
1 parent 3f54cfb commit 6c80b86
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/Encryptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ public function __construct(string $hashKey, string $hashIv)
$this->hashIv = $hashIv;

$this->cipher = new AES('cbc');
// $this->cipher->disablePadding();
$this->cipher->setKey($this->hashKey);
$this->cipher->setIv($this->hashIv);
}

public function encrypt(array $data): string
{
$this->cipher->enablePadding();

return bin2hex($this->cipher->encrypt(http_build_query($data)));
}

public function decrypt(string $plainText): string
{
$this->cipher->disablePadding();

return self::stripPadding($this->cipher->decrypt(hex2bin($plainText)));
}

Expand Down
6 changes: 6 additions & 0 deletions src/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Omnipay\NewebPay\Message\CompletePurchaseRequest;
use Omnipay\NewebPay\Message\FetchTransactionRequest;
use Omnipay\NewebPay\Message\PurchaseRequest;
use Omnipay\NewebPay\Message\VoidRequest;
use Omnipay\NewebPay\Traits\HasDefaults;

/**
Expand Down Expand Up @@ -61,4 +62,9 @@ public function fetchTransaction(array $options = []): RequestInterface
{
return $this->createRequest(FetchTransactionRequest::class, $options);
}

public function void(array $options = []): RequestInterface
{
return $this->createRequest(VoidRequest::class, $options);
}
}
101 changes: 101 additions & 0 deletions src/Message/VoidRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace Omnipay\NewebPay\Message;

use Omnipay\Common\Exception\InvalidResponseException;
use Omnipay\NewebPay\Traits\HasDefaults;

class VoidRequest extends AbstractRequest
{
use HasDefaults;

protected $liveEndpoint = 'https://core.newebpay.com/API/CreditCard/Cancel';

protected $testEndpoint = 'https://ccore.newebpay.com/API/CreditCard/Cancel';

public function getEndpoint()
{
return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
}

/**
* 藍新金流交易序號.
* 與商店訂單編號二擇一填入
*
* @param string $value
* @return self
*/
public function setTradeNo($value)
{
return $this->setTransactionReference($value);
}

/**
* @return ?string
*/
public function getTradeNo()
{
return $this->getTransactionReference();
}

/**
* 單號類別.
* 只限定填數字 1 或 2
* 1 表示使用商店訂單編號
* 2 表示使用藍新金流交易單號
*
* @param int $value
* @return self
*/
public function setIndexType($value)
{
return $this->setParameter('IndexType', $value);
}

/**
* @return int
*/
public function getIndexType()
{
return $this->getParameter('IndexType') ?: 1;
}

public function getData()
{
$data = array_filter([
'RespondType' => $this->getRespondType(),
'Version' => $this->getVersion() ?: '1.0',
'Amt' => (int) $this->getAmount(),
'MerchantOrderNo' => $this->getTransactionId(),
'TradeNo' => $this->getTransactionReference(),
'IndexType' => $this->getIndexType(),
'TimeStamp' => $this->getTimeStamp(),
], static function ($value) {
return $value !== null && $value !== '';
});

return $data;
}

/**
* @throws InvalidResponseException
*/
public function sendData($data)
{
$response = $this->httpClient->request('POST', $this->getEndpoint(), [
'Content-Type' => 'application/x-www-form-urlencoded',
], http_build_query([
'MerchantID_' => $this->getMerchantID(),
'PostData_' => $this->encrypt($data),
]));

$result = [];
parse_str(trim((string) $response->getBody()), $result);

if (! hash_equals($result['CheckCode'], $this->checkCode($result))) {
throw new InvalidResponseException('Incorrect CheckCode');
}

return $this->response = new VoidResponse($this, $result);
}
}
31 changes: 31 additions & 0 deletions src/Message/VoidResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Omnipay\NewebPay\Message;

class VoidResponse extends AbstractResponse
{
public function isSuccessful()
{
return $this->getCode() === 'SUCCESS';
}

public function getCode()
{
return $this->data['Status'];
}

public function getMessage()
{
return $this->data['Message'];
}

public function getTransactionId()
{
return $this->data["MerchantOrderNo"];
}

public function getTransactionReference()
{
return $this->data["TradeNo"];
}
}
3 changes: 2 additions & 1 deletion src/Traits/HasDefaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,10 @@ public function encrypt(array $data)
public function decrypt(string $plainText)
{
$encryptor = new Encryptor($this->getHashKey(), $this->getHashIv());
$result = $encryptor->decrypt($plainText);

$data = [];
parse_str($encryptor->decrypt($plainText), $data);
parse_str($result, $data);

return $data;
}
Expand Down
33 changes: 33 additions & 0 deletions tests/GatewayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Omnipay\Common\Message\NotificationInterface;
use Omnipay\NewebPay\Gateway;
use Omnipay\NewebPay\Message\FetchTransactionRequest;
use Omnipay\NewebPay\Message\VoidRequest;
use Omnipay\Tests\GatewayTestCase;

class GatewayTest extends GatewayTestCase
Expand Down Expand Up @@ -133,4 +134,36 @@ public function testFetchTransaction()
parse_str((string) $this->getMockClient()->getLastRequest()->getBody(), $postData);
self::assertEquals('CD326F689018E7862727547F85CECD7DD7AE0FDB7782DE2C1E46B4417245B51F', $postData['CheckValue']);
}

public function testVoid()
{
$this->setMockHttpResponse('VoidSuccess.txt');

$timestamp = 1641348593;
$request = $this->gateway->void([
'RespondType' => 'String',
'Version' => '1.0',
'TimeStamp' => $timestamp,
'Amt' => '30',
'MerchantOrderNo' => "Vanespl_ec_".$timestamp,
'IndexType' => '1',
'PayerEmail' => 'tek.chen@ezpay.com.tw',
]);

self::assertInstanceOf(VoidRequest::class, $request);

$response = $request->send();

self::assertTrue($response->isSuccessful());
self::assertEquals('SUCCESS', $response->getCode());
self::assertEquals('放棄授權成功', $response->getMessage());
self::assertEquals('Vanespl_ec_1641348593', $response->getTransactionId());
self::assertEquals('23111221191660146', $response->getTransactionReference());

parse_str((string) $this->getMockClient()->getLastRequest()->getBody(), $postData);
self::assertEquals(
'61d27f528031d936b29c87802479e4e51e9cc72935abba1cade58c7524504e72a86f00fe167dca60eefc3f9c17917154a7c626641829b6bac38e3863b97c1b11a91399194a674a8fc2820c2247954fc5b16a2094e89a3fa79b15b3bf0c8dbf0677b7420af3e5c528426e1e0e6c41206b',
$postData['PostData_']
);
}
}
13 changes: 13 additions & 0 deletions tests/Mock/VoidFailed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Strict-Transport-Security: max-age=63072000
X-Akamai-Transformed: 9 234 0 pmb=mRUM,1
Expires: Sun, 12 Nov 2023 13:33:03 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Sun, 12 Nov 2023 13:33:03 GMT
Content-Length: 234
Connection: keep-alive
Server-Timing: cdn-cache; desc=MISS, edge; dur=55, origin; dur=51, ak_p; desc="1699795982548_1752377015_139633467_10571_2669_5_828_-";dur=1

Status=TRA10047&Message=該交易不為授權成功狀態,不可放棄授權&MerchantID=MS350766787&Amt=500&MerchantOrderNo=test002&TradeNo=23111221191660146&CheckCode=479CE7E56302B9E30275BD0C440AC47D4F8A519D2C893C64BC172A35A9A473B6
13 changes: 13 additions & 0 deletions tests/Mock/VoidSuccess.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Strict-Transport-Security: max-age=63072000
X-Akamai-Transformed: 9 234 0 pmb=mRUM,1
Expires: Sun, 12 Nov 2023 13:33:03 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Sun, 12 Nov 2023 13:33:03 GMT
Content-Length: 234
Connection: keep-alive
Server-Timing: cdn-cache; desc=MISS, edge; dur=55, origin; dur=51, ak_p; desc="1699795982548_1752377015_139633467_10571_2669_5_828_-";dur=1

Status=SUCCESS&Message=放棄授權成功&MerchantID=MS127874575&Amt=30&MerchantOrderNo=Vanespl_ec_1641348593&TradeNo=23111221191660146&CheckCode=A71CAB190914DD9432C49B49AA71A5A291EFFFBFFE149417818C0E04D3BEB40B

0 comments on commit 6c80b86

Please sign in to comment.