---
title: "Fasáda Purchases — Purchases for Laravel | Roundly"
description: "Všetky metódy fasády Purchases — result() a handle() pre požiadavky, sync() a replay() pre hotové výsledky, for($owner) a vyhľadanie poskytovateľov."
url: https://roundly-consulting.com/sk/open-source/navody/purchases-for-laravel/fasada-purchases
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Purchases for Laravel](https://roundly-consulting.com/sk/open-source/navody/purchases-for-laravel.md)

# Fasáda Purchases

RoundlyConsulting\\Purchases\\Facades\\Purchases je odporúčaný vstupný bod. result() overí a dekóduje požiadavku do výsledku ProviderResult nezávislého od poskytovateľa a nič nezapisuje; handle() urobí to isté, potom uloží model a spustí udalosti životného cyklu. sync() a replay() uložia výsledky, ktoré neprišli ako webhook, a for($owner) obmedzí dopyty na jedného vlastníka:

```php
use RoundlyConsulting\Purchases\Facades\Purchases;

$result = Purchases::result('stripe', $request);   // verify + decode, no writes
$result->type();        // ResultType::Subscription
$result->status();      // Status enum
$result->providerId();  // provider-side id

$model = Purchases::handle('stripe', $request);     // verify + decode + persist + events
$model = Purchases::sync($result);                  // persist a result you already hold (?Model)
$model = Purchases::replay($notification);          // re-run one audited notification (?Model)

Purchases::for($user)->subscribedTo('pro');        // one owner's purchases and subscriptions

Purchases::provider('google');   // Provider (throws UnknownProviderException if absent)
Purchases::providers();          // Collection<string, Provider>
Purchases::has('apple');         // bool
Purchases::ids();                // ['apple', 'google', 'stripe']
```

## Prehľad metód

| Metóda | Vracia | Čo robí |
| --- | --- | --- |
| `result($id, $request)` | `ProviderResult` | Overí a dekóduje požiadavku — nič nezapisuje. |
| `handle($id, $request)` | `Model` | Overí, dekóduje, uloží a spustí udalosti; rešpektuje queue.enabled. |
| `sync(ProviderResult $result)` | `?Model` | Uloží výsledok, ktorý už máte, s auditom ako pri webhooku, vždy synchrónne. |
| `replay(PurchaseNotification\|int $notification)` | `?Model` | Znova spracuje jednu uloženú auditnú notifikáciu a označí ju ako spracovanú. |
| `for(Model $owner)` | `OwnerPurchases` | Nákupy a predplatné jedného vlastníka — len čítanie. |
| `provider($id)` | `Provider` | Vráti poskytovateľa; ak nie je nakonfigurovaný, UnknownProviderException. |
| `providers()` | `Collection<string, Provider>` | Všetci poskytovatelia podľa id. |
| `has($id)` | `bool` | Či je poskytovateľ zaregistrovaný. |
| `ids()` | `list<string>` | Identifikátory registrovaných poskytovateľov. |
| `fake()` | `PurchasesFake` | Nasadí zaznamenávajúci spy — pozrite Testovanie. |

## Čo vracia handle()

- Vždy — požiadavka sa najprv synchrónne overí; neplatný podpis vyhodí VerificationException ešte pred akýmkoľvek zápisom.
- Fronta vypnutá (predvolene) — uložený Purchase, Subscription alebo PurchaseRefund.
- Fronta zapnutá — auditný záznam PurchaseNotification, ktorý opisuje, čo sa zaradilo do fronty, alebo neuložený zástupný objekt, ak je auditný log vypnutý.
- Informatívny výsledok (zmena preferencie obnovy v Apple, odklad v Google, TEST, nenamapovaná udalosť Stripe …) — nič sa neuloží, žiadna udalosť sa nespustí a vráti sa spracovaná auditná notifikácia.

## Uloženie výsledku, ktorý už máte

sync() uloží ProviderResult presne tak ako webhook — s auditom, premietnutý do Purchase, Subscription alebo PurchaseRefund, so spustenými udalosťami a auditným záznamom označeným ako spracovaný — a vždy synchrónne. Použite ho pre účtenku, ktorú vaša aplikácia overila sama, alebo pre GenericResult zostavený pri dopĺňaní histórie. Nič znova neoveruje, preto mu nikdy neodovzdávajte neoverené dáta z klienta; auditný záznam to uvádza pravdivo — signature\_verified je false a origin je NotificationOrigin::Host:

```php
use RoundlyConsulting\Purchases\Enum\ResultType;
use RoundlyConsulting\Purchases\Enum\Status;
use RoundlyConsulting\Purchases\Facades\Purchases;
use RoundlyConsulting\Purchases\Results\GenericResult;

// A Google Play purchase token your app sent up, checked against the Play Developer API
// (product() throws VerificationException unless the purchase is in a purchased state).
$purchase = Purchases::provider('google')->product($productId, $token);

$model = Purchases::sync(new GenericResult(   // ?Model — null for an informational result
    provider: 'google',
    type: ResultType::Purchase,
    providerId: $purchase->orderId ?? $token,  // the key Google's own notifications use
    status: Status::Completed,
    transactionId: $purchase->orderId,
    name: $productId,
    productId: $productId,
));
```

Ak uloženie zlyhá (napríklad chybou listenera), auditný záznam zostane nespracovaný, takže ho replay() môže dokončiť neskôr.

## Opätovné spracovanie jednej notifikácie

replay() obnoví výsledok z uloženej PurchaseNotification, znova ho uloží a označí ju ako spracovanú. Ukladanie je zoradené podľa času udalosti (pozrite Udalosti), takže opätovné spracovanie notifikácie — či celého logu — nikdy nevráti nákup ani predplatné do staršieho stavu a nikdy nespustí udalosť životného cyklu pre niečo, čo už bolo uplatnené. Spracuje overenú notifikáciu poskytovateľa aj záznam s pôvodom host zapísaný cez sync(); záznam poskytovateľa, ktorého podpis sa neoveril, soft-deleted alebo neuloženú notifikáciu či snapshot, ktorý sa už nedá obnoviť, odmietne výnimkou InvalidProviderNotificationException a neznáme id výnimkou ModelNotFoundException:

```php
Purchases::replay($notification);   // ?Model — the PurchaseNotification model …
Purchases::replay(42);              // … or its id
```

## Nákupy jedného vlastníka

for($owner) vráti objekt OwnerPurchases obmedzený presne na daného vlastníka — jeho morph typ aj kľúč —, takže vlastník iného modelu s rovnakým id sa do výsledkov nedostane a neuložený vlastník nevidí nič. Model vlastníka nepotrebuje žiadny trait:

```php
use RoundlyConsulting\Purchases\Facades\Purchases;

Purchases::for($user)->subscribedTo('pro');            // bool
Purchases::for($user)->activeSubscription('pro');      // ?Subscription (latest active)
Purchases::for($user)->purchases()->latest()->get();   // Builder<Purchase>
Purchases::for($user)->subscriptions()->count();       // Builder<Subscription>
```

| Metóda | Vracia | Popis |
| --- | --- | --- |
| `purchases()` | `Builder<Purchase>` | Nákupy vlastníka, pripravené na ďalšie reťazenie. |
| `subscriptions()` | `Builder<Subscription>` | Predplatné vlastníka, pripravené na ďalšie reťazenie. |
| `activeSubscription(?string $name = null)` | `?Subscription` | Posledné aktívne predplatné, voliteľne podľa názvu plánu. |
| `subscribedTo(string $name)` | `bool` | Či má vlastník aktívne predplatné daného plánu. |

Vlastníka nastavujete vy. Notifikácia obchodu nikdy neuvádza, ktorému z vašich používateľov patrí, preto každý záznam uložený cez webhook, handle(), sync() či replay() začína bez vlastníka — for($user) ani HasPurchases ho neuvidia, kým ho neprepojíte, zvyčajne v listeneri (pozrite Udalosti).

## Názvy plánov

subscribedTo($name) a activeSubscription($name) porovnávajú Subscription::$name. Apple a Google pomenujú predplatné podľa identifikátora produktu (com.example.pro) pri každej notifikácii, takže upgrade ho premenuje. Stripe plán nepomenúva: nové predplatné zo Stripe dostane názov podľa produktu svojej ceny (prod\_…) a už sa nepremenuje, takže názov, ktorý mu dáte vy — napríklad pro —, vydrží aj všetky ďalšie udalosti.

## Použitie vo vlastnej route

Pribalená webhook routa je voliteľná. Ak chcete mať endpoint plne pod kontrolou, volajte handle() z vlastnej routy a neúspešné overenie premeňte na 400 — presne to robí pribalený controller. Obchody posielajú požiadavky bez CSRF tokenu, preto routu umiestnite mimo CSRF ochrany:

```php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use RoundlyConsulting\Purchases\Exceptions\VerificationException;
use RoundlyConsulting\Purchases\Facades\Purchases;

Route::post('billing/stripe/webhook', function (Request $request) {
    try {
        Purchases::handle('stripe', $request);
    } catch (VerificationException) {
        abort(400);
    }

    return response()->noContent();
});
```

## Vyhľadanie poskytovateľov

```php
use RoundlyConsulting\Purchases\Facades\Purchases;

if (Purchases::has('google')) {
    $google = Purchases::provider('google');   // RoundlyConsulting\Purchases\Providers\Google\Google
}

foreach (Purchases::providers() as $id => $provider) {
    // 'apple' => Apple, 'google' => Google, 'stripe' => Stripe
}
```

Poskytovatelia sa vytvárajú cez kontajner a sú kľúčovaní podľa id() — pre vstavaných apple, google a stripe. provider() vyhodí UnknownProviderException pre identifikátor, ktorý nie je zaregistrovaný.

## 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](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

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

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/purchases-for-laravel.md)
