Lue dans les fichiers PHP du paquet au commit e18549a5e42a : ses espaces de noms, classes, interfaces et énumérations, leurs constantes, propriétés et méthodes publiques avec leur PHPDoc, et les options que prennent ses fabriques. Rien n’en est exécuté.
ConfigclassA gateway's configuration while its factory builds it: the options given, the factory's defaults under them, and the keys that must be filled.
3 methods
GatewayclassA provider's actions behind one door: the first action supporting a request answers it.
25 methods
GatewayFactoryclassThe Omnibus way: a provider's factory fills a Config - its name, title, the options it needs, its API client ("omnitrade.api", a closure of the Config) and its actions ("omnitrade.action.<name>") - and the gateway is those actions, the API handed to the ones that ask for it.
4 methods
GatewayFactoryInterfaceinterfaceBuilds a provider's gateway from its options (credentials, sandbox...).
2 methods
GatewayInterfaceinterfaceOne provider, configured - a payment service (Stripe, PayPal) or a commerce platform (Shopify, WooCommerce): the same questions for all of them, about payments, the catalogue, connected accounts and subscriptions. Each typed method is a shortcut for execute() with its request; a provider that does not do something throws RequestNotSupportedException, and supports() says so beforehand.
24 methods
RegistryclassThe shop's providers by name, each built once from its factory and options:
8 methods
ActionInterfaceinterfaceOne thing a provider does: answers the requests it supports.
2 methods
ApiAwareInterfaceinterfaceAn action that talks to the provider through the gateway's API client.
1 method
ApiAwareTraittrait1 method
OmnitradeBundleclassOmnitrade in a Symfony application: the provider packages installed (omnitrade/stripe, omnitrade/paypal, omnitrade/shopify, omnitrade/woocommerce, omnitrade/web, omnitrade/amazon) registered, the shop's gateways built from configuration, Omnitrade\Registry autowired, and each gateway injectable by its name:
2 methods
InvalidConfigExceptionclassA gateway misconfigured: a credential missing, an unknown factory.
InvalidNotificationExceptionclassA webhook that is not the provider's: its signature does not hold, or it is too old.
OmnitradeExceptioninterfaceEvery exception Omnitrade throws.
ProviderExceptionclassThe provider refused, or could not be reached: any HTTP error status (401, 403, 404, 429, 5xx), a transport failure, an answer that cannot be read.
1 method · 2 properties
RequestNotSupportedExceptionclassThe provider does not do that (no authorizations, no platform orders...).
1 method
RedactionclassWhat a failed call may carry of its credentials, taken out before the failure leaves the package: an HTTP client's exception quotes the URL called (a key in its query, a password in its user part), and every exception's trace keeps the arguments of the calls under it (the request options, headers and query with the key) unless PHP runs with zend.exception_ignore_args.
5 methods · 1 constant
AccountclassA connected account: somebody else's account at the provider, opened through the platform (Stripe Connect), that payments may be sent to.
2 methods · 12 properties · 3 constants
CustomerclassWho pays: what a provider wants to know of them, all optional.
1 method · 8 properties
LineclassOne line of what is paid for, as the provider's page or invoice lists it.
2 methods · 7 properties
MediaclassA picture (or a film) of a product, as the platform serves it.
1 method · 6 properties · 2 constants
MerchantclassWho sells: the shop itself on a platform of one's own, one seller among many on a marketplace. An Offer names it when it is not the shop.
1 method · 4 properties
MoneyclassAn amount in a currency's minor units (cents): 1250 EUR is 12,50 €.
7 methods · 2 properties
NotificationclassWhat a provider is telling us, checked: one event about one transaction.
4 methods · 11 properties
OfferclassA price at which a variant can be bought, and from whom: on a platform of one's own there is one (the shop's), on a marketplace there may be several.
1 method · 7 properties
OptionclassWhat a product's variants differ by - "Millésime: 2018, 2019", "Format: 75 cl, Magnum" - as the platform declares it. A variant says its own value of each in ProductVariant::$options.
1 method · 2 properties
PaymentclassWhat to charge, and everything a provider may want with it. The amount is the truth; the lines are for the buyer's eyes (a hosted page), and a provider that cannot take them as given charges the amount as one line.
2 methods · 16 properties
PaymentMethodclassOne way a provider takes money: a card, a wallet, a bank debit.
1 method · 5 properties · 5 constants
PlatformOrderclassA commerce platform's order (Shopify, WooCommerce): the sale as it stands there.
1 method · 11 properties
ProductclassA product as a platform has it - Shopify, WooCommerce, Stripe Products, a marketplace listing - normalized: its texts, its brand, its key/value attributes, its options, its variants with their offers and stock, its pictures. What the platform answered is kept whole in $raw.
4 methods · 17 properties · 3 constants
ProductPageclassOne page of a catalogue: its products, and the cursor of the next page when there is one.
2 methods · 2 properties
ProductVariantclassOne thing one can put in a cart: a vintage, a size, a colour of a product.
3 methods · 11 properties
ReferenceclassWhich product is meant: the platform's id for it, or the address of its page (a shop's product page, a marketplace listing). A provider reads the one it understands; of() tells them apart.
6 methods · 2 properties
RefundclassMoney given back, as the provider recorded it.
1 method · 7 properties
StatusenumWhere a transaction stands, whatever the provider calls it.
2 methods · 8 cases
StockclassHow many of a variant are left, as the platform counts them. A platform that does not track it says $tracked = false and $quantity = null: as many as one likes.
2 methods · 6 properties
SubscriptionclassA subscription as the provider has it: who pays (the provider's customer), for what (its price), whether it runs, until when the paid period lasts and whether it stops there.
3 methods · 14 properties · 7 constants
TransactionclassA payment as the provider knows it: its reference there, where it stands, and - PENDING with a $redirectUrl - the page the buyer must be sent to.
5 methods · 12 properties
AccountLinkclassThe provider's page where a connected account's holder gives what is asked (identity, bank account), valid a few minutes, used once. Result: its URL. $returnUrl is where they come back when done or tired (ask FetchAccount what is still missing), $refreshUrl where they land when the link ran out: make a new one there.
2 methods · 4 properties · 2 constants
AffiliateLinkclassThe address that sends a buyer to a product with the site's affiliate tag (a shop's partner programme): omnitrade/amazon writes it with the Associates tag, omnitrade/web with the query parameters configured per host. Result: the URL, or null when the provider has no programme for that product (use the plain address).
2 methods · 2 properties
AuthorizeclassReserve the money; Capture takes it, VoidAuthorization lets it go. Result: the Transaction.
2 methods · 1 property
CancelSubscriptionclassStop a subscription: at the end of the period already paid (the default - what was paid for is kept until then) or at once. Result: the Subscription as it stands after.
2 methods · 2 properties
CaptureclassTake the money reserved by an authorization, all of it or $amount. Result: the Transaction.
2 methods · 3 properties
CreateAccountclassOpen a connected account for somebody the platform sends payments to (a seller, the host of a fund): an Express account by default - the provider holds its dashboard and its identity checks. Result: the Account, not ready yet; AccountLink gives the page where its holder completes it.
2 methods · 7 properties
FetchAccountclassA connected account as the provider has it now: ready or not, and what is missing. Result: the Account.
2 methods · 1 property
FetchInventoryclassWhat is left of these variants (their ids at the platform; none: every variant it tracks). Result: Stock[], one per variant answered.
2 methods · 1 property
FetchOrderclassA commerce platform's order, by its id there. Result: the PlatformOrder.
2 methods · 1 property
FetchProductclassOne product, by the platform's id or the address of its page. Result: the Product, or null when there is no such product.
2 methods · 1 property
FetchProductsclassA page of the catalogue: from the cursor the previous page gave (null: the first), only what changed since $updatedSince when given, only what matches $query when given (the platform's own search). Result: a ProductPage.
2 methods · 4 properties
FetchSubscriptionclassA subscription as the provider has it now. Result: the Subscription.
2 methods · 1 property
FetchTransactionclassThe transaction as the provider has it now. Result: the Transaction.
2 methods · 1 property
GetPaymentMethodsclassWhat the provider can take, for this amount and country when given. Result: PaymentMethod[]
2 methods · 2 properties
NotifyclassWhat the provider sent to the webhook: the raw body and the request's headers, for the signature. Result: the Notification, or InvalidNotificationException when the signature does not hold.
3 methods · 2 properties
PurchaseclassTake the money. Result: the Transaction - PAID when it is taken at once, PENDING with a redirectUrl when the buyer must go and pay on a page and come back (then notify() or fetch() says).
2 methods · 1 property
RefundclassGive money back on a transaction, all of it or $amount. Result: the Refund.
2 methods · 4 properties
RequestclassA question put to a gateway. The action that supports it answers by setting the result; the gateway hands the request back.
3 methods
SubscribeclassStart a subscription: the payment's amount is taken now and then every interval, on a page the buyer is sent to. Result: the Transaction - PENDING with a redirectUrl; notify() then tells of the first payment and, through Notification::$subscription, of the subscription and its life.
2 methods · 6 properties · 1 constant
SubscriptionPortalclassThe provider's page where a subscriber changes their card, reads their invoices or stops their subscription. Result: its URL, valid a short while. $customer is the provider's customer (Subscription::$customer).
2 methods · 3 properties
VoidAuthorizationclassLet an authorization go without taking the money. Result: the Transaction, CANCELLED.
2 methods · 1 property
GatewayContractTeststraitWhat every Omnitrade provider does, as PHPUnit tests, offline: a provider's test case uses this trait, gives its factory (built on the HTTP client the suite hands it) and fake options, and the provider's recorded answers for the operations it supports.
12 methods
Omnitrade
Config class
final class Config extends ArrayObject Config.php:13
A gateway's configuration while its factory builds it: the options given, the factory's defaults under them, and the keys that must be filled.
Config::defaults()
public function defaults(array $defaults): selfSets each key not set yet.
Config::validateNotEmpty()
public function validateNotEmpty(array $keys): voidConfig::get()
public function get(string $key, mixed $default = null): mixedGateway class
final class Gateway implements GatewayInterface Gateway.php:22
A provider's actions behind one door: the first action supporting a request answers it.
Gateway::__construct()
public function __construct(readonly string $name, readonly string $title, readonly array $actions)Gateway::getName()
public function getName(): stringGateway::getTitle()
public function getTitle(): stringGateway::supports()
public function supports(string $request): boolGateway::execute()
public function execute(Request\Request $request): Request\RequestGateway::purchase()
public function purchase(Payment $payment): TransactionGateway::authorize()
public function authorize(Payment $payment): TransactionGateway::capture()
public function capture(string $reference, ?Money $amount = null, ?string $idempotencyKey = null): TransactionGateway::refund()
public function refund(string $reference, ?Money $amount = null, ?string $idempotencyKey = null, ?string $reason = null): RefundModelGateway::void()
public function void(string $reference): TransactionGateway::fetch()
public function fetch(string $reference): TransactionGateway::paymentMethods()
public function paymentMethods(?Money $for = null, ?string $country = null): arrayGateway::notify()
public function notify(string $body, array $headers = []): NotificationGateway::fetchOrder()
public function fetchOrder(string $reference): PlatformOrderGateway::fetchProduct()
public function fetchProduct(Reference|string $reference): ?ProductGateway::fetchProducts()
public function fetchProducts(?string $cursor = null, ?\DateTimeInterface $updatedSince = null, ?string $query = null, int $limit = 50): ProductPageGateway::fetchInventory()
public function fetchInventory(array $references = []): arrayGateway::affiliateLink()
public function affiliateLink(Reference|string $reference, ?string $tag = null): ?stringGateway::createAccount()
public function createAccount(string $country, ?string $email = null, string $type = Account::EXPRESS, array $metadata = []): AccountGateway::accountLink()
public function accountLink(string $reference, string $returnUrl, string $refreshUrl): stringGateway::fetchAccount()
public function fetchAccount(string $reference): AccountGateway::subscribe()
public function subscribe(Payment $payment, string $interval = 'month', int $intervalCount = 1, ?string $price = null): TransactionGateway::fetchSubscription()
public function fetchSubscription(string $reference): SubscriptionGateway::cancelSubscription()
public function cancelSubscription(string $reference, bool $atPeriodEnd = true): SubscriptionGateway::subscriptionPortal()
public function subscriptionPortal(string $customer, string $returnUrl, ?string $locale = null): stringGatewayFactory class
abstract class GatewayFactory implements GatewayFactoryInterface GatewayFactory.php:16
The Omnibus way: a provider's factory fills a Config - its name, title, the options it needs, its API client ("omnitrade.api", a closure of the Config) and its actions ("omnitrade.action.<name>") - and the gateway is those actions, the API handed to the ones that ask for it.
GatewayFactory::__construct()
public function __construct(protected readonly ?HttpClientInterface $http = null)GatewayFactory::getName()
public function getName(): stringGatewayFactory::create()
public function create(array $options = []): GatewayInterfaceGatewayFactory::createConfig()
public function createConfig(array $options = []): ConfigGatewayFactoryInterface interface
interface GatewayFactoryInterface GatewayFactoryInterface.php:6
Builds a provider's gateway from its options (credentials, sandbox...).
GatewayFactoryInterface::getName()
public function getName(): stringThe name gateways are configured with: "stripe", "paypal", "shopify".
..
GatewayFactoryInterface::create()
public function create(array $options = []): GatewayInterfaceGatewayInterface interface
interface GatewayInterface GatewayInterface.php:28
One provider, configured - a payment service (Stripe, PayPal) or a commerce platform (Shopify, WooCommerce): the same questions for all of them, about payments, the catalogue, connected accounts and subscriptions. Each typed method is a shortcut for execute() with its request; a provider that does not do something throws RequestNotSupportedException, and supports() says so beforehand.
GatewayInterface::getName()
public function getName(): stringGatewayInterface::getTitle()
public function getTitle(): stringGatewayInterface::supports()
public function supports(string $request): boolGatewayInterface::execute()
public function execute(Request $request): Request- Returns
answered
- Throws
Exception\RequestNotSupportedException
- Throws
Exception\ProviderException
GatewayInterface::purchase()
public function purchase(Payment $payment): TransactionTake the money, now or through a page the buyer is sent to (a redirect, then notify()).
GatewayInterface::authorize()
public function authorize(Payment $payment): TransactionReserve the money; capture() takes it, void() lets it go.
GatewayInterface::capture()
public function capture(string $reference, ?Money $amount = null, ?string $idempotencyKey = null): Transaction$amountpart of the authorization, or all of it
GatewayInterface::refund()
public function refund(string $reference, ?Money $amount = null, ?string $idempotencyKey = null, ?string $reason = null): Refund$amountpart of the payment, or all of it
GatewayInterface::void()
public function void(string $reference): TransactionGatewayInterface::fetch()
public function fetch(string $reference): TransactionThe transaction as the provider has it now.
GatewayInterface::paymentMethods()
public function paymentMethods(?Money $for = null, ?string $country = null): array- Returns
what the provider can take, for this amount and country when given
GatewayInterface::notify()
public function notify(string $body, array $headers = []): NotificationWhat the provider is telling us (a webhook): checked against its signature, read as one event about one transaction.
- Throws
Exception\InvalidNotificationException when the signature does not hold
GatewayInterface::fetchOrder()
public function fetchOrder(string $reference): PlatformOrderA platform's own order (Shopify, WooCommerce): the sale as it stands there.
GatewayInterface::fetchProduct()
public function fetchProduct(Reference|string $reference): ?ProductOne product, by the platform's id or the address of its page; null when there is none.
GatewayInterface::fetchProducts()
public function fetchProducts(?string $cursor = null, ?\DateTimeInterface $updatedSince = null, ?string $query = null, int $limit = 50): ProductPageA page of the catalogue, from a cursor, changed since a date, matching a search.
GatewayInterface::fetchInventory()
public function fetchInventory(array $references = []): array$referencesthe variants, by their ids there (none: all)
GatewayInterface::affiliateLink()
public function affiliateLink(Reference|string $reference, ?string $tag = null): ?stringThe address that sends a buyer to a product with the site's affiliate tag; null when there is no programme for it.
GatewayInterface::createAccount()
public function createAccount(string $country, ?string $email = null, string $type = Account::EXPRESS, array $metadata = []): AccountOpen a connected account (Express by default) the platform will send payments to.
GatewayInterface::accountLink()
public function accountLink(string $reference, string $returnUrl, string $refreshUrl): stringThe provider's page where the account's holder completes it.
GatewayInterface::fetchAccount()
public function fetchAccount(string $reference): AccountGatewayInterface::subscribe()
public function subscribe(Payment $payment, string $interval = 'month', int $intervalCount = 1, ?string $price = null): TransactionStart a subscription on a page the buyer is sent to: the payment's amount now, then every interval.
GatewayInterface::fetchSubscription()
public function fetchSubscription(string $reference): SubscriptionGatewayInterface::cancelSubscription()
public function cancelSubscription(string $reference, bool $atPeriodEnd = true): SubscriptionStop a subscription, at the end of the paid period unless told otherwise.
GatewayInterface::subscriptionPortal()
public function subscriptionPortal(string $customer, string $returnUrl, ?string $locale = null): stringThe provider's page where a subscriber manages their subscription.
Registry class
final class Registry Registry.php:15
The shop's providers by name, each built once from its factory and options:
new Registry([new StripeGatewayFactory($http)], [ 'card' => ['factory' => 'stripe', 'options' => [...]], ]);
Registry::__construct()
public function __construct(iterable $factories, readonly array $config)Registry::get()
public function get(string $name): GatewayInterfaceRegistry::has()
public function has(string $name): boolRegistry::options()
public function options(string $name): array- Returns
the options a gateway is configured with
Registry::create()
public function create(string $name, array $overrides = []): GatewayInterfaceA gateway built afresh, its configured options with $overrides over them - keys typed in a back office, say. Not kept: get() still gives the configured one.
Registry::names()
public function names(): array- Returns
the configured gateways' names
Registry::all()
public function all(): arrayRegistry::factories()
public function factories(): array- Returns
the factories installed: what
factory:may name
Omnitrade\Action
ActionInterface interface
interface ActionInterface ActionInterface.php:8
One thing a provider does: answers the requests it supports.
ActionInterface::supports()
public function supports(Request $request): boolActionInterface::execute()
public function execute(Request $request): voidSets the request's result, or throws Omnitrade\Exception\ProviderException.
ApiAwareInterface interface
interface ApiAwareInterface ApiAwareInterface.php:6
An action that talks to the provider through the gateway's API client.
ApiAwareInterface::setApi()
public function setApi(object $api): voidApiAwareTrait trait
trait ApiAwareTrait ApiAwareTrait.php:10
ApiAwareTrait::setApi()
public function setApi(object $api): voidOmnitrade\Bridge\Symfony
OmnitradeBundle class
final class OmnitradeBundle extends AbstractBundle OmnitradeBundle.php:39
Omnitrade in a Symfony application: the provider packages installed (omnitrade/stripe, omnitrade/paypal, omnitrade/shopify, omnitrade/woocommerce, omnitrade/web, omnitrade/amazon) registered, the shop's gateways built from configuration, Omnitrade\Registry autowired, and each gateway injectable by its name:
omnitrade: gateways: card: { factory: stripe, options: { api_key: '%env(STRIPE_API_KEY)%', webhook_secret: '%env(STRIPE_WEBHOOK_SECRET)%' } } paypal: { factory: paypal, options: { client_id: '%env(PAYPAL_CLIENT_ID)%', secret: '%env(PAYPAL_SECRET)%', sandbox: true } }
public function __construct(GatewayInterface $card) }An application's own factories (a GatewayFactoryInterface) are registered too, autoconfigured.
OmnitradeBundle::configure()
public function configure(DefinitionConfigurator $definition): voidOmnitradeBundle::loadExtension()
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): voidOmnitrade\Exception
InvalidConfigException class
final class InvalidConfigException extends LogicException implements OmnitradeException InvalidConfigException.php:6
A gateway misconfigured: a credential missing, an unknown factory.
InvalidNotificationException class
final class InvalidNotificationException extends ProviderException InvalidNotificationException.php:6
A webhook that is not the provider's: its signature does not hold, or it is too old.
OmnitradeException interface
interface OmnitradeException extends Throwable OmnitradeException.php:6
Every exception Omnitrade throws.
ProviderException class
class ProviderException extends RuntimeException implements OmnitradeException ProviderException.php:11
The provider refused, or could not be reached: any HTTP error status (401, 403, 404, 429, 5xx), a transport failure, an answer that cannot be read.
The family's rule (docs/providers.md): a provider throws this, never its HTTP client's or its library's exception.
public readonly string $providerpublic readonly ?string $providerCodeThe provider's own error code, when it gave one
ProviderException::__construct()
public function __construct(public readonly string $provider, string $message, public readonly ?string $providerCode = null, ?\Throwable $previous = null)RequestNotSupportedException class
final class RequestNotSupportedException extends LogicException implements OmnitradeException RequestNotSupportedException.php:8
The provider does not do that (no authorizations, no platform orders...).
RequestNotSupportedException::for()
public static function for(Request $request, string $gateway): selfOmnitrade\Http
Redaction class
final class Redaction Redaction.php:22
What a failed call may carry of its credentials, taken out before the failure leaves the package: an HTTP client's exception quotes the URL called (a key in its query, a password in its user part), and every exception's trace keeps the arguments of the calls under it (the request options, headers and query with the key) unless PHP runs with zend.exception_ignore_args.
copy() gives the previous exception to wrap instead of the client's own: the same class and code, its message with the key's parameters, the user part and every secret value replaced by ***, its trace without arguments, its own previous copied the same way. Properties of the client's class beyond those of \Exception are not copied (a Symfony HttpException's response, a PSR-18 exception's request: their URL holds the key). withoutArguments() takes the arguments out of the trace of the exception thrown in its place.
const MASK = '***'
Redaction::secrets()
public static function secrets(string $url, array $options = []): arrayThe secrets a request carries: the values of its query parameters, headers and body fields named as credentials (key, token, secret, password, signature, auth...), a bearer token, a basic password, the URL's user part.
$optionsthe HTTP client's options
Redaction::sensitive()
public static function sensitive(string $name): boolWhether a parameter, header or field of this name holds a credential.
Redaction::text()
public static function text(string $text, array $secrets = []): stringA text without credentials: in every address, the user part and the parameters named as credentials masked (api_key=***); then every secret given, raw or URL-encoded, masked wherever it stands.
Redaction::copy()
public static function copy(\Throwable $failure, array $secrets = []): \ThrowableA copy of a failure to wrap in its place: its class, code, file and line, its message through text(), its trace without arguments, its previous copied the same way.
Redaction::withoutArguments()
public static function withoutArguments(\Throwable $failure): \ThrowableThe failure given, the arguments out of its trace (and out of its previous ones'), as zend.exception_ignore_args would have left it.
Omnitrade\Model
Account class
final readonly class Account Account.php:12
A connected account: somebody else's account at the provider, opened through the platform (Stripe Connect), that payments may be sent to.
It can be paid to once the provider has what it asks of its holder: $chargesEnabled and $payoutsEnabled say so; $requirements lists what is still missing.
const EXPRESS = 'express'const STANDARD = 'standard'const CUSTOM = 'custom'public string $providerpublic string $referenceThe provider's id: "acct_1Nv0...".
public string $typepublic ?string $countrypublic ?string $emailpublic bool $detailsSubmittedThe holder gave everything the onboarding asked.
public bool $chargesEnabledpublic bool $payoutsEnabledpublic array $requirementspublic ?string $defaultCurrencypublic array $metadatapublic array $raw
Account::__construct()
public function __construct(public string $provider, public string $reference, public string $type = self::EXPRESS, public ?string $country = null, public ?string $email = null, public bool $detailsSubmitted = false, public bool $chargesEnabled = false, public bool $payoutsEnabled = false, public array $requirements = [], public ?string $defaultCurrency = null, public array $metadata = [], public array $raw = [])Account::isReady()
public function isReady(): boolPayments may be sent to it, and it may be paid out.
Customer class
final readonly class Customer Customer.php:6
Who pays: what a provider wants to know of them, all optional.
public ?string $emailpublic ?string $namepublic ?string $referenceThe provider's own id for them, when they have one (Stripe's cus_...).
public ?string $phonepublic array $streetpublic ?string $postalCodepublic ?string $citypublic ?string $countryISO 3166-1 alpha-2.
Customer::__construct()
public function __construct(public ?string $email = null, public ?string $name = null, public ?string $reference = null, public ?string $phone = null, public array $street = [], public ?string $postalCode = null, public ?string $city = null, public ?string $country = null)Line class
final readonly class Line Line.php:6
One line of what is paid for, as the provider's page or invoice lists it.
public string $labelpublic Money $unitAmountpublic int $quantitypublic ?string $skupublic ?string $imageUrlpublic ?string $referenceThe provider's own id for it, when it has one (a Shopify variant gid, a WooCommerce product id).
public bool $physicalGoods to post, as opposed to a service or a download.
Line::__construct()
public function __construct(public string $label, public Money $unitAmount, public int $quantity = 1, public ?string $sku = null, public ?string $imageUrl = null, public ?string $reference = null, public bool $physical = false)Line::total()
public function total(): MoneyMedia class
final readonly class Media Media.php:6
A picture (or a film) of a product, as the platform serves it.
const IMAGE = 'image'const VIDEO = 'video'public string $urlpublic ?string $altpublic string $typepublic ?int $widthpublic ?int $heightpublic ?string $referenceThe platform's id for it, when it has one.
Media::__construct()
public function __construct(public string $url, public ?string $alt = null, public string $type = self::IMAGE, public ?int $width = null, public ?int $height = null, public ?string $reference = null)Merchant class
final readonly class Merchant Merchant.php:9
Who sells: the shop itself on a platform of one's own, one seller among many on a marketplace. An Offer names it when it is not the shop.
public string $namepublic ?string $referencepublic ?string $urlpublic ?string $countryISO 3166-1 alpha-2.
Merchant::__construct()
public function __construct(public string $name, public ?string $reference = null, public ?string $url = null, public ?string $country = null)Money class
final readonly class Money Money.php:6
An amount in a currency's minor units (cents): 1250 EUR is 12,50 €.
public string $currencypublic int $amount
Money::__construct()
public function __construct(public int $amount, string $currency)Money::of()
public static function of(int $amount, string $currency): selfMoney::equals()
public function equals(self $other): boolMoney::decimal()
public function decimal(): stringIn major units, as a provider's decimal API expects ("12.50"); yen and the like have none.
Money::fromDecimal()
public static function fromDecimal(string|float $decimal, string $currency): selfFrom a provider's decimal ("12.50"), to minor units.
Money::minorDigits()
public static function minorDigits(string $currency): intHow many minor digits a currency has: 2 for most, 0 for JPY, KRW..., 3 for BHD, KWD.
..
Money::__toString()
public function __toString(): stringNotification class
final readonly class Notification Notification.php:16
What a provider is telling us, checked: one event about one transaction.
The event is the provider's own name for it; $status is what it means for the transaction when it means anything (null for a hint to ignore), and $transaction the transaction as the event carries it, when it does.
A catalogue event (a product created, changed or deleted, a stock level moved) is one too, as are a connected account's ($account) and a subscription's ($subscription: started, renewed, past due, ended): $reference is then the product's id there, $product the product as the event carries it (null for a deletion), $stocks the levels.
public string $providerpublic string $eventThe provider's event type: "checkout.session.completed", "orders/paid".
..
public ?string $referenceThe transaction (or platform order) it concerns, by its reference there.
public ?Status $statuspublic ?Transaction $transactionpublic ?string $idThe provider's id for the event, to handle it once.
public array $rawpublic ?Product $productpublic array $stockspublic ?Account $accountA connected account's event ("account.updated"): the account as it stands.
public ?Subscription $subscriptionA subscription's event (created, renewed, changed, ended): the subscription as it stands.
Notification::__construct()
public function __construct(public string $provider, public string $event, public ?string $reference = null, public ?Status $status = null, public ?Transaction $transaction = null, public ?string $id = null, public array $raw = [], public ?Product $product = null, public array $stocks = [], public ?Account $account = null, public ?Subscription $subscription = null)Notification::isAccount()
public function isAccount(): boolNotification::isSubscription()
public function isSubscription(): boolNotification::isCatalogue()
public function isCatalogue(): boolAbout the catalogue rather than a payment.
Offer class
final readonly class Offer Offer.php:9
A price at which a variant can be bought, and from whom: on a platform of one's own there is one (the shop's), on a marketplace there may be several.
public Money $pricepublic ?Money $compareAtThe struck-through price ("compare at"), when the platform shows one.
public bool $availablepublic ?string $urlWhere to buy it (the product page, a seller's listing).
public ?Merchant $merchantnull: the shop itself.
public ?string $referenceThe platform's id for this price, when it has one (a Stripe price).
public ?bool $taxIncludedTaxes included in $price, as the platform says.
Offer::__construct()
public function __construct(public Money $price, public ?Money $compareAt = null, public bool $available = true, public ?string $url = null, public ?Merchant $merchant = null, public ?string $reference = null, public ?bool $taxIncluded = null)Option class
final readonly class Option Option.php:10
What a product's variants differ by - "Millésime: 2018, 2019", "Format: 75 cl, Magnum" - as the platform declares it. A variant says its own value of each in ProductVariant::$options.
public string $namepublic array $values
Option::__construct()
public function __construct(public string $name, public array $values = [])Payment class
final readonly class Payment Payment.php:19
What to charge, and everything a provider may want with it. The amount is the truth; the lines are for the buyer's eyes (a hosted page), and a provider that cannot take them as given charges the amount as one line.
$reference is yours - the order's -, sent to the provider as the merchant reference. $idempotencyKey makes the same purchase asked twice happen once, at providers that honour one (Stripe does): give it per attempt, and keep it with the attempt.
$destination and $applicationFee make it a payment for someone else: taken by the platform, sent to a connected account (Request\CreateAccount), the platform keeping its fee.
public Money $amountpublic string $referencepublic ?string $descriptionpublic ?Customer $customerpublic array $linespublic ?Money $shippingPosting, on top of the lines; and money off, taken from them. Both inside $amount.
public ?Money $discountpublic ?string $returnUrlWhere the buyer comes back after a hosted page, paid or not.
public ?string $cancelUrlpublic ?string $idempotencyKeypublic ?string $methodA provider's payment method to insist on ("card", "sepa_debit"...), else its choice.
public ?string $noticeA mention to print on the page and the receipt: why there is no VAT, for instance.
public array $metadatapublic ?string $localeBCP 47, for the provider's page.
public ?string $destinationA connected account the money goes to (Stripe Connect's destination charge: "acct_..."): the platform takes the payment and passes it on, keeping $applicationFee. Null: the money is the platform's own.
public ?Money $applicationFeeWhat the platform keeps of a payment sent to $destination; inside $amount.
Payment::__construct()
public function __construct(public Money $amount, public string $reference, public ?string $description = null, public ?Customer $customer = null, public array $lines = [], public ?Money $shipping = null, public ?Money $discount = null, public ?string $returnUrl = null, public ?string $cancelUrl = null, public ?string $idempotencyKey = null, public ?string $method = null, public ?string $notice = null, public array $metadata = [], public ?string $locale = null, public ?string $destination = null, public ?Money $applicationFee = null)Payment::linesAddUp()
public function linesAddUp(): boolWhether the lines, the shipping and the discount add up to the amount, in its currency: then a page may list them.
PaymentMethod class
final readonly class PaymentMethod PaymentMethod.php:6
One way a provider takes money: a card, a wallet, a bank debit.
const CARD = 'card'const WALLET = 'wallet'const BANK = 'bank'const BUY_NOW_PAY_LATER = 'bnpl'const OTHER = 'other'public string $codeAs the provider names it: "card", "paypal", "sepa_debit", "klarna".
..
public string $labelpublic string $kindOne of the constants above.
public array $currenciespublic array $raw
PaymentMethod::__construct()
public function __construct(public string $code, public string $label, public string $kind = self::OTHER, public array $currencies = [], public array $raw = [])PlatformOrder class
final readonly class PlatformOrder PlatformOrder.php:6
A commerce platform's order (Shopify, WooCommerce): the sale as it stands there.
public string $providerpublic string $referenceThe platform's id.
public ?string $numberThe number people see ("#1042").
public Status $statuspublic Money $totalpublic ?Customer $customerpublic array $linespublic ?string $financialStatusThe platform's own payment state and fulfilment state, as it names them.
public ?string $fulfillmentStatuspublic ?\DateTimeImmutable $createdAtpublic array $raw
PlatformOrder::__construct()
public function __construct(public string $provider, public string $reference, public ?string $number, public Status $status, public Money $total, public ?Customer $customer = null, public array $lines = [], public ?string $financialStatus = null, public ?string $fulfillmentStatus = null, public ?\DateTimeImmutable $createdAt = null, public array $raw = [])Product class
final readonly class Product Product.php:11
A product as a platform has it - Shopify, WooCommerce, Stripe Products, a marketplace listing - normalized: its texts, its brand, its key/value attributes, its options, its variants with their offers and stock, its pictures. What the platform answered is kept whole in $raw.
const ACTIVE = 'active'const DRAFT = 'draft'const ARCHIVED = 'archived'public string $providerpublic string $referenceThe platform's id.
public string $titlepublic ?string $descriptionHTML, as the platform holds it.
public ?string $handleIts handle or slug there.
public ?string $brandShopify's vendor, WooCommerce's brand, a "brand" metadata.
public ?string $urlThe product page, when there is one.
public string $statusself::ACTIVE, DRAFT or ARCHIVED.
public array $categoriespublic array $attributespublic array $optionspublic array $variantspublic array $mediapublic ?Merchant $merchantWho sells it, when it is not the shop itself.
public ?\DateTimeImmutable $updatedAtpublic array $raw
Product::__construct()
public function __construct(public string $provider, public string $reference, public string $title, public ?string $description = null, public ?string $handle = null, public ?string $brand = null, public ?string $url = null, public string $status = self::ACTIVE, public array $tags = [], public array $categories = [], public array $attributes = [], public array $options = [], public array $variants = [], public array $media = [], public ?Merchant $merchant = null, public ?\DateTimeImmutable $updatedAt = null, public array $raw = [])Product::isActive()
public function isActive(): boolProduct::variant()
public function variant(string $reference): ?ProductVariantProduct::price()
public function price(): ?MoneyThe lowest price of its variants' first offers.
ProductPage class
final readonly class ProductPage ProductPage.php:6
One page of a catalogue: its products, and the cursor of the next page when there is one.
public array $productspublic ?string $nextHand it to the next FetchProducts; null on the last page.
ProductPage::__construct()
public function __construct(public array $products = [], public ?string $next = null)ProductPage::hasMore()
public function hasMore(): boolProductVariant class
final readonly class ProductVariant ProductVariant.php:6
One thing one can put in a cart: a vintage, a size, a colour of a product.
public string $referencepublic ?string $titlenull for a product's only variant ("Default Title" at Shopify).
public ?string $skupublic ?string $barcodepublic array $offerspublic array $optionspublic ?Stock $stockpublic ?Media $imagepublic array $attributespublic ?int $weightGrams.
public array $raw
ProductVariant::__construct()
public function __construct(public string $reference, public ?string $title = null, public ?string $sku = null, public ?string $barcode = null, public array $offers = [], public array $options = [], public ?Stock $stock = null, public ?Media $image = null, public array $attributes = [], public ?int $weight = null, public array $raw = [])ProductVariant::offer()
public function offer(): ?OfferThe first offer: the shop's own price.
ProductVariant::price()
public function price(): ?MoneyReference class
final readonly class Reference Reference.php:10
Which product is meant: the platform's id for it, or the address of its page (a shop's product page, a marketplace listing). A provider reads the one it understands; of() tells them apart.
public ?string $idpublic ?string $url
Reference::__construct()
public function __construct(public ?string $id = null, public ?string $url = null)Reference::of()
public static function of(string|self $idOrUrl): self"gid://shopify/Product/42", "prod_Q1x", "1234" or "https://shop.example/products/margaux".
Reference::isUrl()
public function isUrl(): boolReference::path()
public function path(): ?stringThe URL's path, without the query: what a provider matches a handle or a slug in.
Reference::slug()
public function slug(): ?stringThe last segment of the URL's path ("margaux-2019" in /products/margaux-2019).
Reference::__toString()
public function __toString(): stringRefund class
final readonly class Refund Refund.php:6
Money given back, as the provider recorded it.
public string $providerpublic string $referenceThe provider's refund id (Stripe's re_...).
public Money $amountpublic Status $statuspublic ?string $transactionReferenceThe transaction refunded.
public ?string $messagepublic array $raw
Refund::__construct()
public function __construct(public string $provider, public string $reference, public Money $amount, public Status $status, public ?string $transactionReference = null, public ?string $message = null, public array $raw = [])Status enum
enum Status Status.php:6
Where a transaction stands, whatever the provider calls it.
case PENDING = 'pending'Started, not settled: the buyer is on the provider's page, a transfer is on its way.
The money is reserved; capture() takes it.
case PAID = 'paid'case REFUSED = 'refused'case CANCELLED = 'cancelled'case EXPIRED = 'expired'case PARTIALLY_REFUNDED = 'partially_refunded'case REFUNDED = 'refunded'
Status::isFinal()
public function isFinal(): boolNothing more will happen to it.
Status::isSettled()
public function isSettled(): boolThe money came in (and may since have gone back).
Stock class
final readonly class Stock Stock.php:10
How many of a variant are left, as the platform counts them. A platform that does not track it says $tracked = false and $quantity = null: as many as one likes.
public string $referenceThe variant (or the product, when it has no variants) by its id there.
public ?int $quantitypublic bool $trackedpublic ?string $skupublic ?string $locationWhere it is held, when the platform counts by location.
public ?string $itemThe platform's own id for the counted item (a Shopify inventory item).
Stock::__construct()
public function __construct(public string $reference, public ?int $quantity, public bool $tracked = true, public ?string $sku = null, public ?string $location = null, public ?string $item = null)Stock::available()
public function available(): boolSubscription class
final readonly class Subscription Subscription.php:10
A subscription as the provider has it: who pays (the provider's customer), for what (its price), whether it runs, until when the paid period lasts and whether it stops there.
const ACTIVE = 'active'const TRIALING = 'trialing'const PAST_DUE = 'past_due'const UNPAID = 'unpaid'const CANCELLED = 'cancelled'const INCOMPLETE = 'incomplete'const PAUSED = 'paused'public string $providerpublic string $referenceThe provider's id: "sub_1Nv0...".
public string $statuspublic ?string $customerThe provider's customer ("cus_..."): what the portal is opened for.
public ?Money $amountpublic ?string $intervalday, week, month, year.
public int $intervalCountpublic ?\DateTimeImmutable $currentPeriodStartpublic ?\DateTimeImmutable $currentPeriodEndpublic bool $cancelAtPeriodEndIt runs to the end of the period, then stops.
public ?\DateTimeImmutable $cancelledAtpublic ?string $priceThe provider's price ("price_...") or product it is for.
public array $metadatapublic array $raw
Subscription::__construct()
public function __construct(public string $provider, public string $reference, public string $status, public ?string $customer = null, public ?Money $amount = null, public ?string $interval = null, public int $intervalCount = 1, public ?\DateTimeImmutable $currentPeriodStart = null, public ?\DateTimeImmutable $currentPeriodEnd = null, public bool $cancelAtPeriodEnd = false, public ?\DateTimeImmutable $cancelledAt = null, public ?string $price = null, public array $metadata = [], public array $raw = [])Subscription::isActive()
public function isActive(): boolWhat it gives is due: running or on trial.
Subscription::isCancelled()
public function isCancelled(): boolTransaction class
final readonly class Transaction Transaction.php:10
A payment as the provider knows it: its reference there, where it stands, and - PENDING with a $redirectUrl - the page the buyer must be sent to.
$raw keeps the provider's whole answer, for what this model leaves out.
public string $providerpublic string $referenceThe provider's id: a Checkout session, a payment intent, a PayPal order.
..
public Status $statuspublic ?Money $amountpublic ?string $redirectUrlpublic ?string $messageThe provider's word on it: a refusal's reason, a pending's cause.
public ?string $providerCodepublic ?string $methodThe provider's payment method, as it names it ("card", "paypal", "sepa_debit").
public ?Money $refundedpublic array $metadatapublic ?\DateTimeImmutable $createdAtpublic array $raw
Transaction::__construct()
public function __construct(public string $provider, public string $reference, public Status $status, public ?Money $amount = null, public ?string $redirectUrl = null, public ?string $message = null, public ?string $providerCode = null, public ?string $method = null, public ?Money $refunded = null, public array $metadata = [], public ?\DateTimeImmutable $createdAt = null, public array $raw = [])Transaction::isRedirect()
public function isRedirect(): boolThe buyer has somewhere to go: a hosted page, a 3-D Secure challenge.
Transaction::isPaid()
public function isPaid(): boolTransaction::isPending()
public function isPending(): boolTransaction::isRefused()
public function isRefused(): boolOmnitrade\Request
AccountLink class
final class AccountLink extends Request AccountLink.php:12
The provider's page where a connected account's holder gives what is asked (identity, bank account), valid a few minutes, used once. Result: its URL. $returnUrl is where they come back when done or tired (ask FetchAccount what is still missing), $refreshUrl where they land when the link ran out: make a new one there.
const ONBOARDING = 'onboarding'const UPDATE = 'update'public readonly string $referencepublic readonly string $returnUrlpublic readonly string $refreshUrlpublic readonly string $type
AccountLink::__construct()
public function __construct(public readonly string $reference, public readonly string $returnUrl, public readonly string $refreshUrl, public readonly string $type = self::ONBOARDING)AccountLink::getUrl()
public function getUrl(): ?stringAffiliateLink class
final class AffiliateLink extends Request AffiliateLink.php:14
The address that sends a buyer to a product with the site's affiliate tag (a shop's partner programme): omnitrade/amazon writes it with the Associates tag, omnitrade/web with the query parameters configured per host. Result: the URL, or null when the provider has no programme for that product (use the plain address).
public readonly Reference $referencepublic readonly ?string $tag
AffiliateLink::__construct()
public function __construct(Reference|string $reference, public readonly ?string $tag = null)AffiliateLink::getUrl()
public function getUrl(): ?stringAuthorize class
final class Authorize extends Request Authorize.php:9
Reserve the money; Capture takes it, VoidAuthorization lets it go. Result: the Transaction.
Authorize::__construct()
public function __construct(public readonly Payment $payment)Authorize::getTransaction()
public function getTransaction(): ?TransactionCancelSubscription class
final class CancelSubscription extends Request CancelSubscription.php:12
Stop a subscription: at the end of the period already paid (the default - what was paid for is kept until then) or at once. Result: the Subscription as it stands after.
public readonly string $referencepublic readonly bool $atPeriodEnd
CancelSubscription::__construct()
public function __construct(public readonly string $reference, public readonly bool $atPeriodEnd = true)CancelSubscription::getSubscription()
public function getSubscription(): ?SubscriptionCapture class
final class Capture extends Request Capture.php:9
Take the money reserved by an authorization, all of it or $amount. Result: the Transaction.
public readonly string $referencepublic readonly ?Money $amountpublic readonly ?string $idempotencyKey
Capture::__construct()
public function __construct(public readonly string $reference, public readonly ?Money $amount = null, public readonly ?string $idempotencyKey = null)Capture::getTransaction()
public function getTransaction(): ?TransactionCreateAccount class
final class CreateAccount extends Request CreateAccount.php:13
Open a connected account for somebody the platform sends payments to (a seller, the host of a fund): an Express account by default - the provider holds its dashboard and its identity checks. Result: the Account, not ready yet; AccountLink gives the page where its holder completes it.
public readonly string $countryISO 3166-1 alpha-2: where its holder lives.
public readonly ?string $emailpublic readonly string $typepublic readonly ?string $businessType"individual" or "company"; null: asked during onboarding.
public readonly array $metadatapublic readonly array $capabilitieswhat it must be able to do: "transfers" (be sent money), "card_payments"
public readonly ?string $idempotencyKey
CreateAccount::__construct()
public function __construct(public readonly string $country, public readonly ?string $email = null, public readonly string $type = Account::EXPRESS, public readonly ?string $businessType = null, public readonly array $metadata = [], public readonly array $capabilities = ['transfers'], public readonly ?string $idempotencyKey = null)$capabilitieswhat it must be able to do: "transfers" (be sent money), "card_payments"
CreateAccount::getAccount()
public function getAccount(): ?AccountFetchAccount class
final class FetchAccount extends Request FetchAccount.php:8
A connected account as the provider has it now: ready or not, and what is missing. Result: the Account.
public readonly string $reference
FetchAccount::__construct()
public function __construct(public readonly string $reference)FetchAccount::getAccount()
public function getAccount(): ?AccountFetchInventory class
final class FetchInventory extends Request FetchInventory.php:11
What is left of these variants (their ids at the platform; none: every variant it tracks). Result: Stock[], one per variant answered.
public readonly array $references
FetchInventory::__construct()
public function __construct(public readonly array $references = [])FetchInventory::getStocks()
public function getStocks(): arrayFetchOrder class
final class FetchOrder extends Request FetchOrder.php:8
A commerce platform's order, by its id there. Result: the PlatformOrder.
public readonly string $reference
FetchOrder::__construct()
public function __construct(public readonly string $reference)FetchOrder::getOrder()
public function getOrder(): ?PlatformOrderFetchProduct class
final class FetchProduct extends Request FetchProduct.php:12
One product, by the platform's id or the address of its page. Result: the Product, or null when there is no such product.
public readonly Reference $reference
FetchProduct::__construct()
public function __construct(Reference|string $reference)FetchProduct::getProduct()
public function getProduct(): ?ProductFetchProducts class
final class FetchProducts extends Request FetchProducts.php:12
A page of the catalogue: from the cursor the previous page gave (null: the first), only what changed since $updatedSince when given, only what matches $query when given (the platform's own search). Result: a ProductPage.
public readonly ?string $cursorpublic readonly ?\DateTimeInterface $updatedSincepublic readonly ?string $querypublic readonly int $limitAt most this many per page; a provider may give fewer.
FetchProducts::__construct()
public function __construct(public readonly ?string $cursor = null, public readonly ?\DateTimeInterface $updatedSince = null, public readonly ?string $query = null, public readonly int $limit = 50)FetchProducts::getPage()
public function getPage(): ProductPageFetchSubscription class
final class FetchSubscription extends Request FetchSubscription.php:8
A subscription as the provider has it now. Result: the Subscription.
public readonly string $reference
FetchSubscription::__construct()
public function __construct(public readonly string $reference)FetchSubscription::getSubscription()
public function getSubscription(): ?SubscriptionFetchTransaction class
final class FetchTransaction extends Request FetchTransaction.php:8
The transaction as the provider has it now. Result: the Transaction.
public readonly string $reference
FetchTransaction::__construct()
public function __construct(public readonly string $reference)FetchTransaction::getTransaction()
public function getTransaction(): ?TransactionGetPaymentMethods class
final class GetPaymentMethods extends Request GetPaymentMethods.php:9
What the provider can take, for this amount and country when given. Result: PaymentMethod[]
public readonly ?Money $forpublic readonly ?string $country
GetPaymentMethods::__construct()
public function __construct(public readonly ?Money $for = null, public readonly ?string $country = null)GetPaymentMethods::getMethods()
public function getMethods(): arrayNotify class
final class Notify extends Request Notify.php:12
What the provider sent to the webhook: the raw body and the request's headers, for the signature. Result: the Notification, or InvalidNotificationException when the signature does not hold.
public readonly string $bodypublic readonly array $headers
Notify::__construct()
public function __construct(public readonly string $body, public readonly array $headers = [])Notify::header()
public function header(string $name): ?stringA header, whatever the case it came in.
Notify::getNotification()
public function getNotification(): ?NotificationPurchase class
final class Purchase extends Request Purchase.php:13
Take the money. Result: the Transaction - PAID when it is taken at once, PENDING with a redirectUrl when the buyer must go and pay on a page and come back (then notify() or fetch() says).
public readonly Payment $payment
Purchase::__construct()
public function __construct(public readonly Payment $payment)Purchase::getTransaction()
public function getTransaction(): ?TransactionRefund class
final class Refund extends Request Refund.php:9
Give money back on a transaction, all of it or $amount. Result: the Refund.
public readonly string $referencepublic readonly ?Money $amountpublic readonly ?string $idempotencyKeypublic readonly ?string $reason
Refund::__construct()
public function __construct(public readonly string $reference, public readonly ?Money $amount = null, public readonly ?string $idempotencyKey = null, public readonly ?string $reason = null)Refund::getRefund()
public function getRefund(): ?RefundModelRequest class
abstract class Request Request.php:9
A question put to a gateway. The action that supports it answers by setting the result; the gateway hands the request back.
Request::setResult()
public function setResult(mixed $result): voidRequest::getResult()
public function getResult(): mixedRequest::isAnswered()
public function isAnswered(): boolSubscribe class
final class Subscribe extends Request Subscribe.php:18
Start a subscription: the payment's amount is taken now and then every interval, on a page the buyer is sent to. Result: the Transaction - PENDING with a redirectUrl; notify() then tells of the first payment and, through Notification::$subscription, of the subscription and its life.
The payment's lines describe what is subscribed to; a provider that keeps its own prices takes $price (a Stripe "price_...") instead of the amount.
const INTERVALS = ['day', 'week', 'month', 'year']public readonly Payment $paymentpublic readonly string $intervalpublic readonly int $intervalCountpublic readonly ?string $priceThe provider's own price, when the plan is kept there.
public readonly ?int $trialDayspublic readonly ?string $customerThe provider's customer, when the buyer already is one ("cus_...").
Subscribe::__construct()
public function __construct(public readonly Payment $payment, public readonly string $interval = 'month', public readonly int $intervalCount = 1, public readonly ?string $price = null, public readonly ?int $trialDays = null, public readonly ?string $customer = null)Subscribe::getTransaction()
public function getTransaction(): ?TransactionSubscriptionPortal class
final class SubscriptionPortal extends Request SubscriptionPortal.php:10
The provider's page where a subscriber changes their card, reads their invoices or stops their subscription. Result: its URL, valid a short while. $customer is the provider's customer (Subscription::$customer).
public readonly string $customerpublic readonly string $returnUrlpublic readonly ?string $localeBCP 47, for the provider's page.
SubscriptionPortal::__construct()
public function __construct(public readonly string $customer, public readonly string $returnUrl, public readonly ?string $locale = null)SubscriptionPortal::getUrl()
public function getUrl(): ?stringVoidAuthorization class
final class VoidAuthorization extends Request VoidAuthorization.php:8
Let an authorization go without taking the money. Result: the Transaction, CANCELLED.
VoidAuthorization::__construct()
public function __construct(public readonly string $reference)VoidAuthorization::getTransaction()
public function getTransaction(): ?TransactionOmnitrade\Testing
GatewayContractTests trait
trait GatewayContractTests GatewayContractTests.php:61
What every Omnitrade provider does, as PHPUnit tests, offline: a provider's test case uses this trait, gives its factory (built on the HTTP client the suite hands it) and fake options, and the provider's recorded answers for the operations it supports.
final class PayPalContractTest extends TestCase { use GatewayContractTests;
protected function factory(HttpClientInterface $http): GatewayFactoryInterface { return new PayPalGatewayFactory($http); }
protected function options(): array { return ['client_id' => 'cid', 'secret' => 'sec', 'webhook_id' => 'WH-1']; }
protected function recordedAnswers(): array { return ['POST /v1/oauth2/token' => ['access_token' => 'A21AA'], ...]; }
}It checks: - the factory's name is the built gateway's, and a Registry builds it from {factory, options}; - each required option missing is an InvalidConfigException (none required: it builds with none); - what supports() denies is refused with RequestNotSupportedException, before any HTTP request; - what supports() grants answers, or fails as a ProviderException - never a TypeError, a JsonException nor an HTTP client's exception - when the provider answers HTTP 401, 403, 404, 429, 500, 503, a body that is not what it should be, or cannot be reached (the family's rule, docs/providers.md); fetchProduct() of what the provider does not have (HTTP 404) is null; - on the recorded answers, for each supported operation: transactions, refunds, payment methods, platform orders and catalogue pages keep their invariants (the gateway's name as provider, non-empty references, money in minor units in an ISO currency, a void CANCELLED, a refund of 5,00 EUR recorded as 500); - notify(): a signed webhook is read as one event, a tampered or unsigned one is an InvalidNotificationException.
No test reaches the network: every request goes to the suite's MockHttpClient, and one with no recorded answer is answered HTTP 404 and named in the failure.
Requires phpunit/phpunit and symfony/http-client (the provider's, in require-dev).
GatewayContractTests::testTheFactoryNamesTheGatewayItBuilds()
public function testTheFactoryNamesTheGatewayItBuilds(): voidGatewayContractTests::testAMissingRequiredOptionIsAConfigurationError()
public function testAMissingRequiredOptionIsAConfigurationError(): voidGatewayContractTests::testWhatItDoesNotSupportIsRefusedAsNotSupported()
public function testWhatItDoesNotSupportIsRefusedAsNotSupported(): voidGatewayContractTests::testWhatItSupportsFailsAsAProviderErrorWhenTheProviderDoes()
public function testWhatItSupportsFailsAsAProviderErrorWhenTheProviderDoes(): voidGatewayContractTests::testAPurchaseIsATransactionInMinorUnits()
public function testAPurchaseIsATransactionInMinorUnits(): voidGatewayContractTests::testAFetchedTransactionKeepsItsInvariants()
public function testAFetchedTransactionKeepsItsInvariants(): voidGatewayContractTests::testCaptureAndVoidAnswerTransactions()
public function testCaptureAndVoidAnswerTransactions(): voidGatewayContractTests::testARefundIsRecordedInMinorUnits()
public function testARefundIsRecordedInMinorUnits(): voidGatewayContractTests::testPaymentMethodsAreDescribed()
public function testPaymentMethodsAreDescribed(): voidGatewayContractTests::testASignedNotificationIsReadAndATamperedOneRefused()
public function testASignedNotificationIsReadAndATamperedOneRefused(): voidGatewayContractTests::testAPlatformOrderKeepsItsInvariants()
public function testAPlatformOrderKeepsItsInvariants(): voidGatewayContractTests::testTheCatalogueIsPagedAndItsProductsKeepTheirInvariants()
public function testTheCatalogueIsPagedAndItsProductsKeepTheirInvariants(): void