NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Shops for Laravel

Platby a doprava

Platby a doprava sú kontrakty driverov; balík neobsahuje SDK žiadneho poskytovateľa. Predvolené implementácie fungujú bez konfigurácie — nulová brána, ktorá vždy uspeje, a doprava zdarma. Pre produkciu naviažte vlastnú implementáciu.

Platobná brána

use RoundlyConsulting\Money\Money;
use RoundlyConsulting\Shops\Contracts\PaymentGateway;
use RoundlyConsulting\Shops\Orders\Order;
use RoundlyConsulting\Shops\Payments\PaymentResult;

final class AcmePayGateway implements PaymentGateway
{
    public function charge(Order $order): PaymentResult
    {
        $due = $order->gatewayAmount();   // total minus store credit — never getFinalPrice()

        // … charge $due->minor() in $due->currency()->code with your provider …

        return PaymentResult::success($due, reference: $chargeId);
    }

    public function refund(Order $order, Money $amount): PaymentResult
    {
        // … refund with your provider …

        return PaymentResult::success($amount, reference: $refundId);
    }
}
// config/shops.php
'payment' => [
    'gateway' => AcmePayGateway::class,
    // ...
],
'shipping' => [
    'method' => FlatRateShipping::class,
],

// Or bind the contract in a service provider — a later binding wins:
$this->app->bind(\RoundlyConsulting\Shops\Contracts\PaymentGateway::class, AcmePayGateway::class);

Platba

use RoundlyConsulting\Shops\Facades\Shops;

$result = Shops::order($order)->charge();   // action form: Actions\Orders\ChargeOrderAction

if (! $result->successful) {
    return back()->withErrors(['payment' => $result->message]);
}

// The order is now Paid — do not call markPaid() again.
$result->amount;      // Money charged through the gateway
$result->reference;   // your provider's reference
  • Platí sa len za objednávku New alebo InProgress; rozhodne sa o tom pod zámkom riadku objednávky ešte pred kreditom či bránou: platba za objednávku Paid, Fulfilled, Canceled alebo Refunded — dvojklik na „Zaplatiť“ alebo druhý request so zastaranou kópiou — vyhodí IllegalStatusTransitionException a nič sa nezaúčtuje.
  • Ak je kredit v obchode zapnutý a ešte neuplatnený a zákazník je Creditable, najprv sa strhne kredit.
  • Nulový zostatok (kredit pokryl objednávku alebo je zadarmo) bránu preskočí a uspeje s nulovou sumou.
  • Inak sa zavolá charge() brány. Dostane Order a musí účtovať $order->gatewayAmount() — nikdy konečnú cenu, ktorá by podiel kreditu zaúčtovala dvakrát.
  • Pri úspechu objednávka prejde New → InProgress (ak je stále New) → Paid. Celá platba — kredit, volanie brány, presun do Paid — beží v jednej transakcii so zámkom objednávky, takže súbežná druhá platba počká a potom sa odmietne. charge() vašej brány obmedzte na samotnú platbu; listenery OrderPaid bežia po potvrdení transakcie.
  • Neúspešná (zamietnutá) platba stav nezmení a neponechá si žiadny kredit. Účtovaná suma zahŕňa zafixovanú dopravu objednávky.
use RoundlyConsulting\Shops\Payments\PaymentResult;

new PaymentResult(bool $successful, Money $amount, ?string $reference = null, ?string $message = null);

PaymentResult::success($amount, reference: 'ch_123');
PaymentResult::failure($amount, message: 'Card declined');

Refundácie

Refundácie zámerne riadi vaša aplikácia: balík nikdy nevolá refund() brány. Sumu (najviac $order->gatewayAmount()) aj to, či sa peniaze vôbec vrátia na kartu, určujete vy — potom objednávku preveďte do nového stavu:

use RoundlyConsulting\Shops\Contracts\PaymentGateway;
use RoundlyConsulting\Shops\Facades\Shops;

// The gateway only took gatewayAmount() — the store-credit share never went through it.
$result = app(PaymentGateway::class)->refund($order, $order->gatewayAmount());

if ($result->successful) {
    Shops::order($order)->refund();   // Paid|Fulfilled → Refunded, fires OrderRefunded
}

// Give back any store-credit share yourself (when refund_to_store_credit is off):
$customer->modifyCreditsMoney($order->store_credit_applied, bucket: 'store_credit');

Pri zapnutom payment.refund_to_store_credit refundáciu cez bránu vynechajte — samotné Shops::order($order)->refund() pripíše celú sumu objednávky ako kredit a obe refundácie naraz by kupujúcemu vrátili peniaze dvakrát.

Doprava

ShippingMethod vypočíta cenu dopravy pre objednávku a cieľovú adresu. Predvolený FreeShippingMethod vráti nulu v mene objednávky s označením Free shipping:

use RoundlyConsulting\Money\Money;
use RoundlyConsulting\Shops\Contracts\ShippingMethod;
use RoundlyConsulting\Shops\Orders\DataTransferObjects\Address;
use RoundlyConsulting\Shops\Orders\Order;

final class FlatRateShipping implements ShippingMethod
{
    public function quote(Order $order, Address $destination): Money
    {
        return $destination->countryIso === 'DE'
            ? Money::ofMinor(490, $order->currency)
            : Money::ofMinor(1290, $order->currency);
    }

    public function label(): string
    {
        return 'Standard delivery';
    }
}
use RoundlyConsulting\Shops\Facades\Shops;

$cost = Shops::order($order)->quoteShipping($order->shipping_address);   // Money

// The action form: app(Actions\Orders\QuoteShippingAction::class)->execute($order, $address)

Pri vytvorení objednávky sa cena dopravy na doručovaciu adresu vypočíta cez naviazanú metódu a zafixuje do objednávky, kde je súčasťou konečnej ceny aj platby — pozrite Vytváranie objednávok. quoteShipping() ocení adresu na požiadanie bez zmeny objednávky.

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.