PHP code example of gulf / payments

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();

   // config/payments.php
   'http' => ['status_endpoint' => [
       'enabled' => true,
       'middleware' => ['web', 'auth', 'can:view,payment'],
   ]],
   

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->

$pending = Payments::flow('pay_now')
    ->charge(Money::of('49.00', 'USD'))
    ->paymentMethod($pmId)
    ->execute();

use Gulf\Payments\Models\Payment;

$pending = Payments::flow('book_pay_later')
    ->hold(Money::of('100.00', 'USD'))
    ->expiresIn(hours: 24)                          // auto-void deadline
    ->for($booking)
    ->onCapture(fn (Payment $p) => /* fulfil */)     // process-local sugar
    ->onExpiry(fn (Payment $p) => /* release */)     // process-local sugar
    ->execute();

use Gulf\Payments\Models\Payment;

$pending = Payments::flow('deposit_balance')
    ->deposit(Money::of('30.00', 'USD'))            // charged now
    ->balance(Money::of('70.00', 'USD'))            // charged later
    ->customer($user->stripe_customer_id)           // 

$pending = Payments::flow('pay_link')
    ->charge(Money::of('25.00', 'USD'))
    ->returnUrl('/pay/success')
    ->cancelUrl('/pay/cancel')
    ->execute();

return redirect($pending->redirectUrl());

$pending = Payments::flow('subscription')
    ->charge(Money::of('19.00', 'USD'))
    ->customer($user->stripe_customer_id)
    ->paymentMethod($pmId)
    ->recurEvery('P1M')   // monthly — needs the 'subscriptions' schema module
    ->execute();

// config/payments.php → 'flows'
'pay_now' => [
    'gateway' => 'stripe',
    'strategy' => 'payment_intent',
    'params' => [
        'capture' => 'automatic',
        'confirmation' => 'automatic',
        'sca' => 'ted_checkout',
    'params' => [
        'mode' => 'payment',
        'success_url' => '/pay/success',
        'cancel_url' => '/pay/cancel',
        'gateway_options' => [
            'customer_email' => '[email protected]',
            'allow_promotion_codes' => true,
        ],
    ],
],

Payments::flow('pay_now')
    ->charge(Money::of('49.00', 'USD'))
    ->withGatewayOptions(['statement_descriptor' => 'ACME STORE'])
    ->execute();

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 

$cus = Payments::customers()->create($profile, $user);   // + local mirror
Payments::customers()->createOrGet($user);               // idempotent + race-safe (owner-unique)
Payments::customers()->attach($cus->reference, 'pm_123'); // fills brand/last4/exp/fingerprint
Payments::customers()->setDefault($cus->reference, 'pm_123'); // invoice_settings.default_payment_method
Payments::customers()->paymentMethods($cus->reference);  // Collection<PaymentMethod>

$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();

use Gulf\Payments\Data\{Money, TransferRequest, PayoutQuery};

// Transfers (platform → connected account) — the SEPARATE-charge money leg.
$tr = Payments::connect()->transfer(new TransferRequest(
    amount: Money::of('90.00','USD'), currency: 'USD',
    destinationAccount: 'acct_seller', transferGroup: 'order_9021',
));                                                            // TransferCreated
Payments::connect()->reverseTransfer($tr->reference, Money::of('30.00','USD')); // TransferReversed (DELTA)

// Connected payouts (connected balance → seller's bank).
Payments::connect()->createPayout('acct_seller', Money::of('90.00','USD'));      // PayoutReceived

// Application-fee refund (Edge 2 single-owner of payment_fees.refunded_amount).
Payments::connect()->refundApplicationFee('fee_123', Money::of('10.00','USD'));  // ApplicationFeeRefunded

class Order extends Model
{
    use Payable;
}

$order->pay()->charge(Money::of('49.00', 'USD'))->paymentMethod($pmId)->execute();

$order->isPaid();          // bool
$order->totalRefunded();   // Money

$schedule->job(new \Gulf\Payments\Jobs\SettleDueSubscriptions)->hourly();

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));

// config/payments.php
'flows' => [
    'my_flow' => ['gateway' => 'stripe', 'strategy' => 'my_strategy'],
],

Payments::registerFlow('my_strategy', App\Payments\MyFlow::class);

// config/payments.php — uncomment the shipped gateways.paymob block, then:
'flows' => [
    'pay_link_paymob' => [
        'gateway' => 'paymob',
        'strategy' => 'hosted_checkout',
        'params' => ['success_url' => '/pay/success', 'cancel_url' => '/pay/cancel'],
    ],
],

$pending = Payments::flow('pay_link_paymob')
    ->charge(Money::of('40.00', 'EGP'))
    ->execute();

return redirect($pending->redirectUrl());   // → the Unified Checkout hosted page

// config/payments.php — uncomment the shipped gateways.myfatoorah block, then:
'flows' => [
    'pay_link_myfatoorah' => [
        'gateway' => 'myfatoorah',
        'strategy' => 'hosted_checkout',
        'params' => ['mode' => 'payment'],
    ],
],

$pending = Payments::flow('pay_link_myfatoorah')
    ->charge(Money::of('12.500', 'KWD'))   // MAJOR-unit decimals (KWD is 3-decimal)
    ->execute();

return redirect($pending->redirectUrl());   // → the MyFatoorah hosted invoice page

// config/payments.php — uncomment the shipped gateways.tabby block, then:
'flows' => [
    'pay_link_tabby' => [
        'gateway' => 'tabby',
        'strategy' => 'hosted_checkout',
        'params' => ['mode' => 'payment'],
    ],
],

$pending = Payments::flow('pay_link_tabby')
    ->charge(Money::of('300.00', 'SAR'))
    ->execute();

return redirect($pending->redirectUrl());   // → the Tabby hosted pay-in-4 page

// later, on fulfillment:
Payments::capture($payment);                // collect the money → Succeeded

// config/payments.php — uncomment the shipped gateways.tamara block, then:
'flows' => [
    'pay_link_tamara' => [
        'gateway' => 'tamara',
        'strategy' => 'hosted_checkout',
        'params' => ['mode' => 'payment'],
    ],
],

$pending = Payments::flow('pay_link_tamara')
    ->charge(Money::of('300.00', 'SAR'))
    ->execute();

return redirect($pending->redirectUrl());   // → the Tamara hosted BNPL page

// later, on fulfillment:
Payments::capture($payment);                // collect the money → Succeeded

// config/payments.php — uncomment the shipped gateways.tap block, then:
'flows' => [
    'pay_link_tap' => ['gateway' => 'tap', 'strategy' => 'hosted_checkout', 'params' => ['mode' => 'payment']],
    'pay_auth_tap' => ['gateway' => 'tap', 'strategy' => 'authorize_capture', 'params' => ['capture' => 'manual']],
],

$pending = Payments::flow('pay_link_tap')
    ->charge(Money::of('3.000', 'KWD'))   // MAJOR-unit decimals (KWD is 3-decimal)
    ->execute();

return redirect($pending->redirectUrl());   // → the Tap hosted card page (transaction.url)

// config/payments.php — uncomment the shipped gateways.paytabs block, then:
'flows' => [
    'pay_link_paytabs' => ['gateway' => 'paytabs', 'strategy' => 'hosted_checkout', 'params' => ['mode' => 'payment']],
    'pay_auth_paytabs' => ['gateway' => 'paytabs', 'strategy' => 'authorize_capture', 'params' => ['capture' => 'manual']],
],

$pending = Payments::flow('pay_link_paytabs')
    ->charge(Money::of('200.00', 'SAR'))   // MAJOR-unit decimals (never minor)
    ->execute();

return redirect($pending->redirectUrl());   // → the PayTabs hosted card page (redirect_url)

// config/payments.php — uncomment the shipped gateways.aps block, then:
'flows' => [
    'pay_link_aps' => ['gateway' => 'aps', 'strategy' => 'hosted_checkout', 'params' => ['mode' => 'payment']],
    'pay_auth_aps' => ['gateway' => 'aps', 'strategy' => 'authorize_capture', 'params' => ['capture' => 'manual']],
],

$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());

// config/payments.php — uncomment the shipped gateways.fawry block, then:
'flows' => [
    'pay_link_fawry' => ['gateway' => 'fawry', 'strategy' => 'hosted_checkout', 'params' => ['mode' => 'payment']],
    'pay_auth_fawry' => ['gateway' => 'fawry', 'strategy' => 'authorize_capture', 'params' => ['capture' => 'manual']],
],

$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
}

// config/payments.php — uncomment the shipped gateways.paypal block, then:
'flows' => [
    'pay_link_paypal' => ['gateway' => 'paypal', 'strategy' => 'hosted_checkout', 'params' => ['mode' => 'payment']],
    'pay_auth_paypal' => ['gateway' => 'paypal', 'strategy' => 'authorize_capture', 'params' => ['capture' => 'manual']],
],

$pending = Payments::flow('pay_link_paypal')->charge(Money::of('100.00', 'USD'))->returnUrl($url)->execute();

return redirect()->away($pending->redirectUrl());   // the PayPal `approve` link
bash
php artisan migrate
bash
   php artisan vendor:publish --tag=payments-frontend
   
bash
   php artisan payments:install --gateway=stripe --stubs
   
bash
php artisan payments:install
bash
   composer 
bash
php artisan migrate
bash
php artisan payments:install --preset=bookings
bash
php artisan payments:make:listener SendReceiptEmail --event=PaymentSucceeded
bash
php artisan payments:make:gateway Tap --key=tap --label="Tap Payments"
php artisan payments:make:flow InstallmentFlow --strategy=installment