1. Go to this page and download the library: Download gulf/payments library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
gulf / payments example snippets
use Gulf\Payments\Facades\Payments;
use Gulf\Payments\Data\Money;
Payments::flow('pay_now')->charge(Money::of('12.50', 'USD'))->execute();
use Gulf\Payments\Facades\Payments;
use Gulf\Payments\Data\Money;
$pending = Payments::flow('pay_now')
->charge(Money::of('12.50', 'USD'))
->customer($user->stripe_customer_id) // optional
->paymentMethod($request->input('pm')) // a Stripe PaymentMethod id (pm_...)
->metadata(['order_id' => $order->id])
->for($order) // optional morph subject on the ledger row
->execute();
// 3-D Secure / next action needed? Hand the gateway-agnostic action to the client.
if ($pending->
Payments::capture($uuid, Money::ofMinor(3000, 'USD')); // partial or full (null)
Payments::void($uuid); // release an uncaptured hold
Payments::refund($uuid, Money::of('5.00', 'USD'), 'requested_by_customer'); // legacy one-shot
Payments::refunds()->of($uuid)->fullAmount()->execute(); // v2 sub-manager (below)
Payments::settleBalance($uuid); // charge the saved balance
Payments::chargeSubscription($subscriptionUuid); // off-session-charge the next renewal period
Payments::find($uuid); // ?PaymentRecord — a read-only lookup
Payments::gateway('stripe')->capture($ref, $amount); // raw driver primitive
use Gulf\Payments\Enums\RefundReason;
Payments::refunds()->of($uuid)->fullAmount()->execute(); // full
Payments::refunds()->of($uuid)
->amount(Money::of('15.00', 'USD'))
->reason(RefundReason::RequestedByCustomer)
->execute(); // partial + reason
Payments::refunds()->list($uuid); // Collection<Data\RefundDetail> (local-first when the module is on)
Payments::refunds()->retrieve($re); // one refund by re_
Payments::refunds()->cancel($re); // ONLY a
$pending = Payments::customers()->saveCard($user, ['return_url' => 'https://app.test/return']);
// $0 row, flow='save_card', keyed on the seti_; RequiresAction/Processing → Succeeded.
use Gulf\Payments\Data\ConnectAccountRequest;
use Gulf\Payments\Enums\AccountType;
$account = Payments::connect()->createAccount(new ConnectAccountRequest(
type: AccountType::Express, country: 'US', email: '[email protected]', owner: $seller,
)); // + local mirror, ConnectedAccountCreated
$link = Payments::connect()->onboardingLink($account->reference, $refreshUrl, $returnUrl);
return redirect()->away($link->url); // single-use, short-lived, NEVER persisted
Payments::connect()->syncAccount($account->reference); // force retrieve + upsert
Payments::connect()->rejectAccount($ref, 'fraud'); // reason validated: {fraud, terms_of_service, other}
Payments::connect()->listAccounts(new ConnectAccountQuery); // Collection (local-first when the module is on)
use Gulf\Payments\Data\Money;
// DIRECT — pi_ ON the connected account (Stripe-Account header + application_fee_amount).
Payments::flow('pay_now')->charge(Money::of('100.00','USD'))
->directTo('acct_seller', Money::of('10.00','USD'))->execute();
// DESTINATION — pi_ on the PLATFORM (transfer_data[destination] + on_behalf_of + fee; NO header).
Payments::flow('pay_now')->charge(Money::of('100.00','USD'))
->onBehalfOf('acct_seller', transferTo: Money::of('90.00','USD'), fee: Money::of('10.00','USD'))->execute();
// SEPARATE — a normal platform charge tagged with a transfer_group; move funds via connect()->transfer().
Payments::flow('pay_now')->charge(Money::of('100.00','USD'))->transferGroup('order_9021')->execute();
class Order extends Model
{
use Payable;
}
$order->pay()->charge(Money::of('49.00', 'USD'))->paymentMethod($pmId)->execute();
$order->isPaid(); // bool
$order->totalRefunded(); // Money
use Gulf\Payments\Jobs\ExpireHeldPayments;
use Gulf\Payments\Jobs\SettleDueBalances;
use Gulf\Payments\Jobs\ReconcilePendingPayments;
use Gulf\Payments\Jobs\SettleDueSubscriptions;
use Gulf\Payments\Jobs\RemindDisputeEvidence;
$schedule->job(new ExpireHeldPayments)->everyFiveMinutes();
$schedule->job(new SettleDueBalances)->hourly();
$schedule->job(new ReconcilePendingPayments)->everyTenMinutes();
$schedule->job(new SettleDueSubscriptions)->hourly(); // needs the 'subscriptions' module
$schedule->job(new RemindDisputeEvidence)->daily(); // needs the 'disputes' module
use Gulf\Payments\Events\PaymentSucceeded;
Event::listen(PaymentSucceeded::class, function (PaymentSucceeded $event) {
$payment = $event->payment; // PaymentRecord
Mail::to(/* … */)->queue(new ReceiptMail($payment));
});
use Gulf\Payments\Facades\Payments;
use Gulf\Payments\Data\Money;
it('charges a booking deposit and settles the balance', function () {
$fake = Payments::fake();
$pending = Payments::flow('deposit_balance')
->deposit(Money::of('30.00', 'USD'))
->balance(Money::of('70.00', 'USD'))
->customer('cus_test')
->paymentMethod('pm_test')
->execute();
$fake->assertInitiated('deposit_balance');
Payments::settleBalance($pending->payment()->uuid());
$fake->assertBalanceSettled($pending->payment()->uuid());
});
Payments::extend('acme', fn ($app, array $config) => new AcmeGateway($config));
$pending = Payments::flow('pay_link_aps')->charge(Money::of('200.00', 'SAR'))->execute();
// APS returns a FORM-POST action, not a GET URL — render the shipped view (redirectUrl() is NOT enough):
return $pending->action()?->type === \Gulf\Payments\Enums\ActionType::RedirectPost
? view('payments::post-redirect', ['action' => $pending->action()])
: redirect()->away($pending->redirectUrl());
$pending = Payments::flow('pay_link_fawry')->charge(Money::of('250.00', 'EGP'))->execute();
// PayAtFawry returns NO redirect — the row sits at `processing`; show the cash reference:
if ($pending->status() === PaymentStatus::Processing && $pending->redirectUrl() === null) {
$reference = $pending->result()->raw->get('referenceNumber'); // customer pays this at any Fawry outlet
}