Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a3dfa35
feat(http-client): Set User-Agent header dynamically
Abraham-Flutterwave Oct 15, 2023
a9128db
fix: Transaction Service Event Tracker
Abraham-Flutterwave Oct 15, 2023
2b8541d
test: Handle PHPSAPI requests
Abraham-Flutterwave Oct 15, 2023
38f6cd4
Update CardTest.php
Abraham-Flutterwave Oct 15, 2023
efc50ae
add SDK_VERSION to environment variables
Abraham-Flutterwave Oct 15, 2023
ad40977
test: New Test cards
Abraham-Flutterwave Oct 15, 2023
d51801f
fix: handle vbssecure auth modes in the card charge service
Abraham-Flutterwave Oct 15, 2023
c0ef792
test: create test provider for TransactionTest
Abraham-Flutterwave Oct 15, 2023
563d04f
example: update card sample with config
Abraham-Flutterwave Oct 15, 2023
b94aed1
dev: update makefile and .gitpod.yml config
Abraham-Flutterwave Oct 15, 2023
dd6b9de
update: change-review workflow
Abraham-Flutterwave Oct 15, 2023
caf302f
update: change-review workflow
Abraham-Flutterwave Oct 15, 2023
367b67b
update: change-review workflow
Abraham-Flutterwave Oct 15, 2023
35713ff
update: change-review workflow
Abraham-Flutterwave Oct 15, 2023
3a747c5
update: change-review workflow include php8.3
Abraham-Flutterwave Oct 15, 2023
24f766f
test: remove dirs from bypass whitelist
Abraham-Flutterwave Oct 15, 2023
23fc6e1
dev: gitpod workspace setup
Abraham-Flutterwave Oct 15, 2023
3bb2015
dev: complete gitpod workspace settings
Abraham-Flutterwave Oct 15, 2023
df276a7
update makefile
Abraham-Flutterwave Oct 15, 2023
2aeab42
test: move bypass finals to checkout test
Abraham-Flutterwave Oct 19, 2023
5f17ac6
remove bypass finals
Abraham-Flutterwave Oct 19, 2023
cc738b3
replace the Config -> PackageConfig
Abraham-Flutterwave Feb 21, 2024
662222c
test: separate checkout test
Abraham-Flutterwave Feb 21, 2024
3de93c7
fix: curlClient namespace
Abraham-Flutterwave Feb 21, 2024
1358abb
update: set default the default modal to standard on checkout
Abraham-Flutterwave Feb 21, 2024
65c6c2a
update setup script
Abraham-Flutterwave Feb 21, 2024
238e83e
fix: handle config override
Abraham-Flutterwave Feb 21, 2024
4305433
tests: exclude vendor folder files
Abraham-Flutterwave Feb 21, 2024
cba7079
refact: update card service
Abraham-Flutterwave Feb 21, 2024
6fce11c
update Bill Service
Abraham-Flutterwave Apr 2, 2025
d142f28
update: Payout Subaccount Event tracker
Abraham-Flutterwave Apr 2, 2025
ab0b23b
FTPI-1072: handle final card status responses.
Abraham-Flutterwave Apr 2, 2025
9403e06
FTPI-1077: Fix Bug omitting customer fullname from the standard check…
Abraham-Flutterwave Apr 8, 2025
13ea9ba
FTPI-1078: support environment variables set with the prefix FLW to f…
Abraham-Flutterwave Apr 8, 2025
6418381
fix: handle getenv function returning false
bajoski34 Apr 8, 2025
88d0230
remove previous keys
bajoski34 Apr 8, 2025
bdde581
FTPI-1081: allow Custom Logger Enhancement
bajoski34 Apr 8, 2025
9f32e3d
include yaml release
bajoski34 Apr 8, 2025
0055081
update: sample release
bajoski34 Apr 8, 2025
8250334
update: sample release
bajoski34 Apr 8, 2025
f56f3b4
update: sample release
bajoski34 Apr 8, 2025
c9940a0
update: sample release
bajoski34 Apr 8, 2025
8631716
update: sample release
bajoski34 Apr 8, 2025
9763d9a
update: sample release
bajoski34 Apr 8, 2025
7d711b3
remove artifact release
bajoski34 Apr 8, 2025
e118248
chore: add artifact release workflow
bajoski34 Apr 9, 2025
3858cef
chore: add php 7.4 artifact
bajoski34 Apr 9, 2025
4722614
docs: Update README instructions to download release artifacts
bajoski34 Apr 9, 2025
1432b78
update sample log directory
bajoski34 Apr 9, 2025
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
3 changes: 3 additions & 0 deletions .docker/.gitpod.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM gitpod/workspace-full

RUN sudo install-packages php-xdebug
9 changes: 5 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PUBLIC_KEY=FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
SECRET_KEY=FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
ENCRYPTION_KEY=FLWSECK_XXXXXXXXXXXXXXXX
ENV=staging
FLW_PUBLIC_KEY=FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
FLW_SECRET_KEY=FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
FLW_ENCRYPTION_KEY=FLWSECK_XXXXXXXXXXXXXXXX
FLW_ENV=staging
FLW_LOG_DIR=logs
44 changes: 44 additions & 0 deletions .github/workflows/artifact-release.yml
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Build and Upload PHP Artifacts

on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+' # Match tags like 1.2.3

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
php: ['7.4', '8.1', '8.2', '8.3', '8.4']

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite

- name: Install dependencies
run: composer install --no-dev --optimize-autoloader

- name: Get tag version
id: tag
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> "$GITHUB_ENV"

- name: Create release artifact
run: |
mkdir -p build
cp -r vendor src tests assets composer.json composer.lock .gitignore LICENSE phpunit.xml.dist .env.example processPayment.php paymentForm.php setup.php README.md CHANGELOG.md build/
cd build && zip -r ../flutterwave-php-${VERSION}-php${{ matrix.php }}.zip . && cd ..

- name: Upload artifact to release
uses: softprops/action-gh-release@v1
with:
files: flutterwave-php-${{ env.VERSION }}-php${{ matrix.php }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16 changes: 6 additions & 10 deletions .github/workflows/change-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: [7.4, 8.1, 8.2]
php: [7.4, 8.1, 8.2, 8.3]

env:
XDEBUG_MODE: coverage
Expand Down Expand Up @@ -48,17 +48,13 @@ jobs:
- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: 'Create env file'
run: |
touch .env
echo PUBLIC_KEY=${PUBLIC_KEY} >> .env
echo SECRET_KEY=${SECRET_KEY} >> .env
echo ENCRYPTION_KEY=${ENCRYPTION_KEY} >> .env
echo ENV=${ENV} >> .env
ls -a ${{ github.workspace }}

- 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
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,6 @@ example.php
.phpunit.cache
coverage.xml
.env.local
.php-cs-fixer.cache
.php-cs-fixer.cache
.idx/
.vscode/
15 changes: 15 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
# and commit this file to your remote git repository to share the goodness with others.

# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart

image:
file: .docker/.gitpod.Dockerfile

tasks:
- init: make

vscode:
extensions:
- felixfbecker.php-debug
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
.PHONY: init
test:
check:
@echo "Installing dependencies..."
@composer install
@echo "Installing dependencies... Done"
@./vendor/bin/pest --coverage --min=0 --coverage-clover ./coverage.xml


test:
@./vendor/bin/pest --coverage --min=0 --coverage-clover ./coverage.xml

debug:
XDEBUG_MODE=coverage ./vendor/bin/pest --coverage --coverage-html .log


12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ Available features include:

## Installation

### Download Release Artifact
If you do not want to make use of composer. each [release](https://github.com/Flutterwave/PHP-v3/releases/) contains a zip with all the dependencies installed. Simply download the one that supports your php version.

### Installation via Composer.

To install the package via Composer, run the following command.
Expand All @@ -67,10 +70,11 @@ cp .env.example .env
Your `.env` file should look this.

```env
PUBLIC_KEY=FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
SECRET_KEY=FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
ENCRYPTION_KEY=FLWSECK_XXXXXXXXXXXXXXXX
ENV='staging/production'
FLW_PUBLIC_KEY=FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
FLW_SECRET_KEY=FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X
FLW_ENCRYPTION_KEY=FLWSECK_XXXXXXXXXXXXXXXX
FLW_ENV='staging/production'
FLW_LOG_DIR=logs
```

### Render Payment Modal
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"ext-openssl": "*",
"guzzlehttp/guzzle": "^7.5",
"psr/http-client": "^1.0",
"psr/log": "^1.1 || ^2.0 || ^3.0",
"php-http/guzzle7-adapter": "^1.0",
"composer/ca-bundle": "^1.3"
},
Expand Down
25 changes: 23 additions & 2 deletions examples/card.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,26 @@

use Flutterwave\Util\AuthMode;
use Flutterwave\Util\Currency;
\Flutterwave\Flutterwave::bootstrap();
use Flutterwave\Config\ForkConfig;
use Dotenv\Dotenv;
// custom config.

if(!file_exists( '.env' )) {
$dotenv = Dotenv::createImmutable(__DIR__."/../");
} else {
$dotenv = Dotenv::createImmutable(__DIR__."/");
}

$dotenv->safeLoad();

$config = ForkConfig::setUp(
$_ENV['SECRET_KEY'],
$_ENV['PUBLIC_KEY'],
$_ENV['ENV'],
$_ENV['ENCRYPTION_KEY']
);

\Flutterwave\Flutterwave::bootstrap($config);

try {

Expand Down Expand Up @@ -48,6 +67,8 @@
$data['customer'] = $customerObj;
$payload = $cardpayment->payload->create($data);



if(!empty($_REQUEST))
{
$request = $_REQUEST;
Expand All @@ -59,7 +80,7 @@

if(isset($request['make'])){
$result = $cardpayment->initiate($payload);

dd($cardpayment);
if($result['mode'] === AuthMode::PIN){
$instruction = $result['instruction'];
require __DIR__."/view/form/pin.php";
Expand Down
6 changes: 6 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
<include>
<directory suffix=".php">./src</directory>
</include>
<exclude>
<directory suffix=".php">./vendor</directory>
<directory suffix=".js">./vendor</directory>
<directory suffix=".xml">./vendor</directory>
<file>tests/bootstrap.php</file>
</exclude>
<report>
<clover outputFile="coverage.xml" />
</report>
Expand Down
24 changes: 21 additions & 3 deletions processPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,33 @@
use Flutterwave\EventHandlers\ModalEventHandler as PaymentHandler;
use Flutterwave\Flutterwave;
use Flutterwave\Library\Modal;
use \Flutterwave\Config\ForkConfig;

# start a session.
// start a session.
session_start();

// Define custom config.
// $myConfig = ForkConfig::setUp(
// 'FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X', //Secret key
// 'FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X', // Public key
// 'FLWSECK_TESTXXXXXXXXXXX', //Encryption key
// 'staging' //Environment Variable
// );

// uncomment the block if you just want to pass the keys with a specific configuration.
// $_ENV['SECRET_KEY'] = "FLWSECK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X";
// $_ENV['PUBLIC_KEY'] = "FLWPUBK_TEST-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-X";
// $_ENV['ENCRYPTION_KEY'] = "FLWSECK_TESTXXXXXXXXXXXX";
// $_ENV['ENV'] = "staging";

// controller default
$controller = null;

try {
Flutterwave::bootstrap();
Flutterwave::bootstrap(); // create a .env or Flutterwave::bootstrap($myConfig)
$customHandler = new PaymentHandler();
$client = new Flutterwave();
$modalType = Modal::POPUP; // Modal::POPUP or Modal::STANDARD
$modalType = Modal::STANDARD; // Modal::POPUP or Modal::STANDARD
$controller = new PaymentController( $client, $customHandler, $modalType );
} catch(\Exception $e ) {
echo $e->getMessage();
Expand Down
32 changes: 22 additions & 10 deletions setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

$flutterwave_installation = 'composer';

if( !file_exists( '.env' )) {
if( !file_exists( '.env' ) && !is_dir('vendor')) {
$dotenv = Dotenv::createImmutable(__DIR__."/../../../"); # on the event that the package is install via composer.
} else {
$flutterwave_installation = "manual";
Expand All @@ -17,7 +17,12 @@
//check if the current version of php is compatible
if(!Helper\CheckCompatibility::isCompatible())
{
echo "Flutterwave: This SDK only support php version ". Helper\CheckCompatibility::MINIMUM_COMPATIBILITY. " or greater.";
if (PHP_SAPI === 'cli') {
echo "❌ Flutterwave: This SDK only support php version ". Helper\CheckCompatibility::MINIMUM_COMPATIBILITY. " or greater.";
} else {
echo "Flutterwave: This SDK only support php version ". Helper\CheckCompatibility::MINIMUM_COMPATIBILITY. " or greater.";
}

exit;
}

Expand All @@ -28,22 +33,29 @@
try{
foreach($flutterwaveKeys as $key)
{
if( empty( $_ENV[ $key ] ) )

$new_key = sprintf( 'FLW_%s', $key );
if(empty($_ENV[ $new_key ]) && empty(\getenv($new_key)) && empty($_ENV[ $key ]) && empty(\getenv($key)))
{
throw new InvalidArgumentException("$key environment variable missing.");
throw new InvalidArgumentException("$new_key or $key environment variable missing.");
}

}
}catch(\Exception $e)
{
echo "<code>Flutterwave sdk: " .$e->getMessage()."</code>";
if (PHP_SAPI === 'cli') {
echo "❌❌Flutterwave sdk: " .$e->getMessage();
echo "Kindly create a .env in the project root and add the required environment variables. ❌". PHP_EOL;
} else {
echo "Flutterwave: Setup incomplete. check your environment variables are set currently. confirm .env contains the required variables.";
}

echo "<br /> Kindly create a <code>.env </code> in the project root and add the required environment variables.";
exit;
}

$keys = [
'SECRET_KEY' => $_ENV['SECRET_KEY'],
'PUBLIC_KEY' => $_ENV['PUBLIC_KEY'],
'ENV' => $_ENV['ENV'],
'ENCRYPTION_KEY' => $_ENV['ENCRYPTION_KEY']
'SECRET_KEY' => $_ENV['FLW_SECRET_KEY'] ?? ($_ENV['SECRET_KEY'] ?? getenv('FLW_SECRET_KEY') ?: getenv('SECRET_KEY')),
'PUBLIC_KEY' => $_ENV['FLW_PUBLIC_KEY'] ?? ($_ENV['PUBLIC_KEY'] ?? getenv('FLW_PUBLIC_KEY') ?: getenv('PUBLIC_KEY')),
'ENV' => $_ENV['FLW_ENV'] ?? ($_ENV['ENV'] ?? getenv('FLW_ENV') ?: getenv('ENV')),
'ENCRYPTION_KEY' => $_ENV['FLW_ENCRYPTION_KEY'] ?? ($_ENV['ENCRYPTION_KEY'] ?? getenv('FLW_ENCRYPTION_KEY') ?: getenv('ENCRYPTION_KEY'))
];
8 changes: 6 additions & 2 deletions src/Config/AbstractConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ abstract class AbstractConfig
public const ENV = 'ENV';
public const DEFAULT_PREFIX = 'FW|PHP';
public const LOG_FILE_NAME = 'flutterwave-php.log';
protected Logger $logger;
public Logger $logger;
protected string $secret;
protected string $public;

Expand All @@ -43,7 +43,11 @@ protected function __construct(string $secret_key, string $public_key, string $e
[
'base_uri' => EnvVariables::BASE_URL,
'timeout' => 60,
RequestOptions::VERIFY => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath()
'headers' => ['User-Agent' => sprintf(
'FlutterwavePHP/%d', EnvVariables::SDK_VERSION
)],
RequestOptions::VERIFY =>
\Composer\CaBundle\CaBundle::getSystemCaRootBundlePath()
]
);

Expand Down
26 changes: 23 additions & 3 deletions src/Config/PackageConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,31 @@ private function __construct(string $secretKey, string $publicKey, string $encry
$this->logger->pushHandler(new RotatingFileHandler(__DIR__ . "../../../../../../" . self::LOG_FILE_NAME, 90));
}

public static function setUp(string $secretKey, string $publicKey, string $enc, string $env): ConfigInterface
public static function setUp(string $secretKey, string $publicKey, string $enc, string $env, ?LoggerInterface $customLogger = null): ConfigInterface
{

if (is_null(self::$instance)) {
return new self($secretKey, $publicKey, $enc, $env);
$instance = new self($secretKey, $publicKey, $enc, $env);
if ($customLogger) {
$instance->logger = $customLogger;
} else {
$rootPath = __DIR__ . '/../../../../../../';
$logDir = $rootPath . $_ENV['FLW_LOG_DIR'] ?? 'logs';

if (!is_dir($logDir)) {
if (!mkdir($logDir, 0775, true) && !is_dir($logDir)) {
throw new \RuntimeException("Flutterwave: Failed to create log directory at $logDir");
}
}

if (!is_writable($logDir)) {
throw new \RuntimeException("Flutterwave: Log directory is not writable: $logDir");
}

$instance->logger->pushHandler(
new RotatingFileHandler($logDir . '/' . self::LOG_FILE_NAME, 90)
);
}
self::$instance = $instance;
}
return self::$instance;
}
Expand Down
Loading