Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM mcr.microsoft.com/devcontainers/base:0-focal

RUN apt-get update && \
apt-get install -y software-properties-common && \
add-apt-repository ppa:ondrej/php -y && \
apt-get update && \
apt-get install -y \
php7.4 php7.4-cli php7.4-common php7.4-curl \
php7.4-mysql php7.4-bcmath php7.4-soap php7.4-zip php7.4-intl \
php7.4-gd php7.4-xsl php7.4-dom php7.4-mbstring \
unzip && \
rm -rf /var/lib/apt/lists/*

RUN curl -sS https://getcomposer.org/installer | php -- \
--install-dir=/usr/local/bin --filename=composer
8 changes: 8 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "Ona",
"build": {
"context": ".",
"dockerfile": "Dockerfile"
},
"postCreateCommand": "ona automations update .ona/automations.yaml"
}
7 changes: 7 additions & 0 deletions .github/workflows/artifact-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ jobs:
id: tag
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> "$GITHUB_ENV"

- name: "Inject SigNoz API key"
shell: bash
env:
SIGNOZ_API_KEY: ${{ secrets.SIGNOZ_API_KEY }}
run: |
sed -i "s|%%SIGNOZ_API_KEY%%|${SIGNOZ_API_KEY}|g" src/Monitoring/SignozServiceLogger.php

- name: Create release artifact
run: |
mkdir -p build
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/change-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [7.4, 8.1, 8.2, 8.3]
php: [7.4, 8.1, 8.2, 8.3, 8.4]

env:
XDEBUG_MODE: coverage
PUBLIC_KEY: ${{ secrets.PUBLIC_KEY }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY }}
ENV: ${{ secrets.ENV }}
SIGNOZ_API_KEY: ${{ secrets.SIGNOZ_API_KEY }}

steps:
- uses: actions/checkout@v3
Expand All @@ -48,14 +49,20 @@ jobs:
- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: "Inject SigNoz API key"
shell: bash
env:
SIGNOZ_API_KEY: ${{ secrets.SIGNOZ_API_KEY }}
run: |
sed -i "s|%%SIGNOZ_API_KEY%%|${SIGNOZ_API_KEY}|g" src/Monitoring/SignozServiceLogger.php

- name: run unit tests and coverage scan
run: ./vendor/bin/pest --coverage --min=20 --coverage-clover ./coverage.xml
env:
PUBLIC_KEY: ${{ secrets.PUBLIC_KEY }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY }}
ENV: ${{ secrets.ENV }}

- name: Upload to Codecov
uses: codecov/codecov-action@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/package-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [7.4, 8.1, 8.2]
php: [7.4, 8.1, 8.2, 8.3, 8.4]

steps:
- uses: actions/checkout@v2
Expand Down
4 changes: 2 additions & 2 deletions paymentForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@
<!-- Replace the value with the payment button text you prefer (optional) -->
<!-- <input type="hidden" name="tx_ref" value="TEST_TXREF_--><?//= uniqid() ?><!--"/>-->
<!-- Replace the value with your transaction reference. It must be unique per transaction. You can delete this line if you want one to be generated for you. -->
<input type="hidden" name="success_url" value="http://request.lendlot.com/13b9gxc1?status=success">
<input type="hidden" name="success_url" value="https://example.com/success">
<!-- Put your success url here -->
<input type="hidden" name="failure_url" value="http://request.lendlot.com/13b9gxc1?status=failed">
<input type="hidden" name="failure_url" value="https://example.com/failure">
<!-- Put your failure url here -->
<center><input id="btn-of-destiny" class="btn btn-warning" type="submit" value="Pay Now"/></center>
</form>
Expand Down
13 changes: 12 additions & 1 deletion processPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use Flutterwave\Library\Modal;
use \Flutterwave\Config\ForkConfig;

// start a session.
// start a session for redirect metadata.
session_start();

// Define custom config.
Expand Down Expand Up @@ -39,9 +39,15 @@
$controller = new PaymentController( $client, $customHandler, $modalType );
} catch(\Exception $e ) {
echo $e->getMessage();
exit();
}

if ($_SERVER["REQUEST_METHOD"] === "POST") {
if ($controller === null) {
echo 'Unable to initialize payment controller.';
exit();
}

$request = $_REQUEST;
$request['redirect_url'] = $_SERVER['HTTP_ORIGIN'] . $_SERVER['REQUEST_URI'];
try {
Expand All @@ -54,6 +60,11 @@
$request = $_GET;
# Confirming Payment.
if(isset($request['tx_ref'])) {
if ($controller === null) {
echo 'Unable to initialize payment controller.';
exit();
}

$controller->callback( $request );
} else {

Expand Down
1 change: 0 additions & 1 deletion setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use Flutterwave\Helper;
use Dotenv\Dotenv;
use Flutterwave\Monitoring\SignozServiceLogger;

$flutterwave_installation = 'composer';

Expand Down
9 changes: 7 additions & 2 deletions src/Config/AbstractConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use Flutterwave\Helper\EnvVariables;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;

abstract class AbstractConfig
{
public const PUBLIC_KEY = 'PUBLIC_KEY';
public const SECRET_KEY = 'SECRET_KEY';
public const ENCRYPTION_KEY = 'ENCRYPTION_KEY';
public const ENV = 'ENV';
public const DEFAULT_PREFIX = 'FW|PHP';
public const DEFAULT_PREFIX = 'FW_PHP';
public const LOG_FILE_NAME = 'flutterwave-php.log';
public Logger $logger;
protected string $secret;
Expand Down Expand Up @@ -55,7 +57,10 @@ protected function __construct(string $secret_key, string $public_key, string $e

$log = new Logger('Flutterwave/PHP');
$this->logger = $log;
$this->signoz = new SignozServiceLogger($this->http, $this->getPublicKey(), $this->getEnv(), null, EnvVariables::SDK_VERSION);
$cache = new Psr16Cache(new FilesystemAdapter('flutterwave_signoz'));
$this->signoz = new SignozServiceLogger($this->http, $this->getPublicKey(), $this->getEnv(), $cache, EnvVariables::SDK_VERSION);
// Track app initialization once per lifecycle
$this->signoz->trackAppCreated($this->getPublicKey());
}

abstract public static function setUp(
Expand Down
28 changes: 6 additions & 22 deletions src/Controller/PaymentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

namespace Flutterwave\Controller;

use Flutterwave\EventHandlers\ModalEventHandler;
use Flutterwave\EventHandlers\EventHandlerInterface;
use Flutterwave\Flutterwave;
use Flutterwave\Entities\Payload;
use Flutterwave\Library\Modal;
use Flutterwave\Service\Transactions;

Expand Down Expand Up @@ -43,14 +41,14 @@ private function getRequestMethod(): string

public function __call(string $name, array $args)
{
if ($this->routes[$name] !== $this->$requestMethod) {
if ($this->routes[$name] !== $this->requestMethod) {
// Todo: 404();
echo "Unauthorized page!";
}
call_user_method_array($name, $this, $args);
call_user_func_array([$this, $name], $args);
}

private function handleSessionData( array $request )
private function handleSessionData(array $request): void
{
$_SESSION['success_url'] = $request['success_url'];
$_SESSION['failure_url'] = $request['failure_url'];
Expand All @@ -61,10 +59,8 @@ private function handleSessionData( array $request )
public function process(array $request)
{
$this->handleSessionData($request);

try {
$_SESSION['p'] = $this->client;

try {
if('inline' === $this->modalType ) {
echo $this->client
->eventHandler($this->handler)
Expand All @@ -87,23 +83,11 @@ public function callback(array $request)
$status = $request['status'];

if (empty($tx_ref)) {
session_destroy();
}

if (!isset($_SESSION['p'])) {
echo "session expired!. please refresh you browser.";
echo 'Missing transaction reference.';
exit();
}

$payment = $_SESSION['p'];

// $payment::setUp([
// 'secret_key' => 'FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X',
// 'public_key' => 'FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X',
// 'encryption_key' => 'FLWSECK_XXXXXXXXXXXXXXXX',
// 'environment' => 'staging'
// ]);

$payment = $this->client;
$payment::bootstrap();

if ('cancelled' === $status) {
Expand Down
81 changes: 60 additions & 21 deletions src/EventHandlers/ModalEventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

namespace Flutterwave\EventHandlers;

use Flutterwave\Service\Transactions;

class ModalEventHandler implements EventHandlerInterface
{
private ?string $success_url = null;
private ?string $failure_url = null;

/**
* This is called when the Rave class is initialized
* */
Expand All @@ -15,6 +20,26 @@ public function onInit($initializationData): void
// Save the transaction to your DB.
}

public function getSuccessUrl(): ?string
{
return $this->success_url;
}

public function setSuccessUrl(?string $success_url): void
{
$this->success_url = $success_url;
}

public function getFailureUrl(): ?string
{
return $this->failure_url;
}

public function setFailureUrl(?string $failure_url): void
{
$this->failure_url = $failure_url;
}

/**
* This is called only when a transaction is successful
* */
Expand All @@ -31,26 +56,34 @@ public function onSuccessful($transactionData): void
// Update the transaction to note that you have given value for the transaction.
// You can also redirect to your success page from here.
if ($transactionData->status === 'successful') {
$currency = $_SESSION['currency'];
$amount = $_SESSION['amount'];
$currency = $_SESSION['currency'] ?? ($transactionData->currency ?? null);
$amount = $_SESSION['amount'] ?? ($transactionData->amount ?? null);

if ($transactionData->currency === $currency && floatval($transactionData->amount) === floatval($amount)) {
header('Location: ' . $_SESSION['success_url']);
session_destroy();
}
if ($currency !== null && $amount !== null) {
if ($transactionData->currency === $currency && floatval($transactionData->amount) === floatval($amount)) {
if (!empty($_SESSION['success_url'])) {
header('Location: ' . $_SESSION['success_url']);
}
session_destroy();
}

if ($transactionData->currency === $currency && floatval($transactionData->amount) < floatval($amount)) {
// TODO: replace this a custom action.
echo "This Event Handler is an Implementation of " . __NAMESPACE__ . "\EventHandlerInterface </br>";
echo "Partial Payment Made ! replace this with your own action! ";
session_destroy();
}
if ($transactionData->currency === $currency && floatval($transactionData->amount) < floatval($amount)) {
// TODO: replace this a custom action.
echo "This Event Handler is an Implementation of " . __NAMESPACE__ . "\EventHandlerInterface </br>";
echo "Partial Payment Made ! replace this with your own action! ";
session_destroy();
}

if ($transactionData->currency !== $currency && floatval($transactionData->amount) === floatval($amount)) {
// TODO: replace this a custom action.
if ($transactionData->currency !== $currency && floatval($transactionData->amount) === floatval($amount)) {
// TODO: replace this a custom action.
echo "This Event Handler is an Implementation of " . __NAMESPACE__ . "\EventHandlerInterface </br>";
echo "Currency mismatch. please look into it ! replace this with your own action ";
session_destroy();
}
} else {
// Fallback when session metadata is unavailable.
echo "This Event Handler is an Implementation of " . __NAMESPACE__ . "\EventHandlerInterface </br>";
echo "Currency mismatch. please look into it ! replace this with your own action ";
session_destroy();
echo "Transaction successful.";
}
} else {
$this->onFailure($transactionData);
Expand All @@ -66,7 +99,9 @@ public function onFailure($transactionData): void
// Update the db transaction record (includeing parameters that didn't exist before the transaction is completed. for audit purpose)
// You can also redirect to your failure page from here.
// TODO: replace this a custom action.
header('Location: ' . $_SESSION['failure_url']);
if (!empty($_SESSION['failure_url'])) {
header('Location: ' . $_SESSION['failure_url']);
}
session_destroy();
}

Expand All @@ -85,8 +120,12 @@ public function onRequeryError($requeryResponse): void
{
echo "Flutterwave: error querying the transaction.";
// trigger webhook notification from Flutterwave.
$service = new Flutterwave\Service\Transaction();
$service->resendFailedHooks($data->id);
$service = new Transactions();
$transactionId = is_object($requeryResponse) && isset($requeryResponse->id)
? (string) $requeryResponse->id
: (string) $requeryResponse;

$service->resendFailedHooks($transactionId);
header('Location: ' . $_SERVER['HTTP_ORIGIN']);
}

Expand All @@ -107,8 +146,8 @@ public function onCancel($transactionReference): void
public function onTimeout($transactionReference, $data): void
{
// trigger webhook notification from Flutterwave.
$service = new Flutterwave\Service\Transaction();
$service->resendFailedHooks($data->id);
$service = new Transactions();
$service->resendFailedHooks((string) ($data->id ?? ''));
header('Location: ' . $_SERVER['HOST']);
}
}
Loading