Skip to content

Commit

Permalink
Initiate idempotent check (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanoandri authored Dec 13, 2024
1 parent a0d9c63 commit 4200cb3
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 14 deletions.
2 changes: 1 addition & 1 deletion modules/gateways/xendit.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
require __DIR__ . '/xendit/autoload.php';

// Module version
const XENDIT_PAYMENT_GATEWAY_VERSION = '2.0.0';
const XENDIT_PAYMENT_GATEWAY_VERSION = '2.1.0';

use WHMCS\Billing\Invoice;
use Xendit\Lib\ActionBase;
Expand Down
7 changes: 7 additions & 0 deletions modules/gateways/xendit/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@
"email": "[email protected]"
}
],
"scripts": {
"test": "export IS_TEST=true & vendor/bin/phpunit tests"
},
"homepage": "https://xendit.co",
"require-dev": {
"phpunit/phpunit": "@stable",
"squizlabs/php_codesniffer": "^3.7"
},
"require": {
"illuminate/database": "^11.34",
"vlucas/phpdotenv": "^5.6"
}
}
46 changes: 46 additions & 0 deletions modules/gateways/xendit/hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*
* @return This depends on the hook function point.
*/
require_once __DIR__ . '/autoload.php';

if (!defined('WHMCS')) {
die('You cannot access this file directly.');
Expand Down Expand Up @@ -58,3 +59,48 @@ function hookClientAreaPageCart($vars)
}

add_hook("ClientAreaPageCart", 1, 'hookClientAreaPageCart');

/**
* Hook to show make Xendit invoice expired when the order is canceled
*
* @param $vars
* @return boolean|void
*/
add_hook('CancelOrder', 1, 'cancelXenditInvoice');

/**
* Hook to show make Xendit invoice expired when the invoice is canceled
*
* @param $vars
* @return boolean|void
*/
add_hook('InvoiceCancelled', 1, 'cancelXenditInvoice');

function cancelXenditInvoice($vars) {
if (!class_exists('\Xendit\Lib\ActionBase') || !class_exists('\Xendit\Lib\Model\XenditTransaction')) {
return false;
}

$actionBase = new \Xendit\Lib\ActionBase();
try {
$flag = "invoiceid";

if ($vars["orderid"]) {
$flag = "orderid";
}

// if the invoice is still active we need to expire the invoice from here
$xenditRequest = $actionBase->getXenditRequest();

$xenditTransactions = $actionBase->getTransactionFromInvoiceId($vars[$flag], $flag);

if ($actionBase->isTransactionsDataValid($xenditTransactions)) {
$xenditRequest->expire($xenditTransactions[0]['transactionid']);

$actionBase->setTransactionsToExpired($xenditTransactions);
}
} catch (\Exception $e) {
logActivity('Error at cancel event hooks >>> '. $e->getMessage(), 0);
}
return true;
}
36 changes: 34 additions & 2 deletions modules/gateways/xendit/lib/ActionBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ public function storeTransaction(array $params = [])
* @param int $invoiceId
* @return mixed
*/
public function getTransactionFromInvoiceId(int $invoiceId)
public function getTransactionFromInvoiceId(int $invoiceId, string $type = "invoiceid")
{
return XenditTransaction::where("invoiceid", $invoiceId)->get();
return XenditTransaction::where($type, $invoiceId)->get();
}

/**
Expand Down Expand Up @@ -363,4 +363,36 @@ public function extractCustomerAddress(array $params): array
];
return array_filter($customerAddressObject);
}

/**
* get xendit request object
*
* @return XenditRequest
*/
public function getXenditRequest()
{
return $this->xenditRequest;
}

/**
* @name setTransactionsToExpired
* @param $transactionsToCancel object
* @return void
*/
public function setTransactionsToExpired($transaction) {
$this->updateTransactions($transaction,
[
'status' => XenditTransaction::STATUS_EXPIRED
]
);
}

/**
* @name isTransactionsDataValid
* @param $transactionsData array
* @return boolean
*/
public function isTransactionsDataValid($transactionsData) {
return !empty($transactionsData) && $transactionsData[0]["transactionid"] !== "";
}
}
8 changes: 1 addition & 7 deletions modules/gateways/xendit/lib/PaymentLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ protected function updateInvoiceStatus(array $params, array $xenditInvoice, $tra

case 'EXPIRED':
$this->updateTransactions($transactions, ['status' => XenditTransaction::STATUS_EXPIRED]);
return $this->generatePaymentLink($params, true);
return $this->generateFormParam($params, $xenditInvoice['invoice_url']);

default:
return $this->generateFormParam($params, $xenditInvoice['invoice_url']);
Expand All @@ -195,12 +195,6 @@ public function generatePaymentLink(array $params, bool $force = false): string
// Get transactions by WHMCS invoice
$transactions = $this->getTransactionFromInvoiceId($params["invoiceid"]);

// Create a new Xendit invoice in case the previous invoice is EXPIRED
if ($force) {
$xenditInvoice = $this->createXenditInvoice($params, $transactions, true);
return $this->generateFormParam($params, $xenditInvoice['invoice_url']);
}

// Get Xendit Invoice by transaction (Xendit invoice_id)
$xenditInvoice = false;
if ($transactions->count() && !empty($transactions[0]->transactionid)) {
Expand Down
22 changes: 18 additions & 4 deletions modules/gateways/xendit/lib/Webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,24 @@ public function getInvoiceIdFromExternalId(string $external_id)
public function confirmInvoice(int $invoiceId, array $xenditInvoiceData, bool $success = true): bool
{
try {
if (!$success) {
// Load WHMCS invoice
$invoice = $this->getInvoice($invoiceId);
// Load Xendit transactions by order id column
$transactionsDataByOrder = $this->getTransactionFromInvoiceId($invoiceId, "orderid");

if (!$success) { // that means it's expired and need to cancel the order
if (!empty($transactionsDataByOrder)) {
// update xendit transactions
$this->setTransactionsToExpired($transactionsDataByOrder);

localAPI('CancelOrder', array(
'orderid' => $transactionsDataByOrder[0]['orderid'],
));

echo 'Success';
} else {
echo 'Transaction not found';
}
return false;
}

Expand All @@ -37,9 +54,6 @@ public function confirmInvoice(int $invoiceId, array $xenditInvoiceData, bool $s
throw new \Exception('Invoice id is incorrect!');
}

// Load WHMCS invoice
$invoice = $this->getInvoice($invoiceId);

$transactionId = $xenditInvoiceData['id'];
$paymentAmount = $this->extractPaidAmount($xenditInvoiceData['paid_amount'], $invoice->total);
$paymentFee = $xenditInvoiceData['fees'][0]['value'];
Expand Down
21 changes: 21 additions & 0 deletions modules/gateways/xendit/lib/XenditRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,27 @@ public function createInvoice(array $param = [])
}
}

/**
* @param array $param
* @return false|string
* @throws \Exception
*/
public function expire(string $invoice_id)
{
try {
$response = $this->request(
'/tpi/payment/xendit/invoice/' . $invoice_id . '/expire',
[
'headers' => $this->defaultHeader()
],
"POST"
);
return $this->processResponse($response);
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}

/**
* @param array $param
* @return false|string
Expand Down

0 comments on commit 4200cb3

Please sign in to comment.