purchase() decides the shape of your checkout. There are three workable flows, and the right one depends on what your provider offers.
Flow 1: Hosted redirect
The provider hosts the payment page. This is the simplest flow and the safest, since card data never touches the installation.UriInterface makes the browser follow it. When the user comes back, completePurchase() verifies the payment.
Flow 2: Your own checkout page
Use this when the provider needs a client-side SDK, or when you must collect something extra, such as a bank choice. Return a relative URI, which resolves against the site root:src/CheckoutView.php
BillingView puts the route under /app/billing and requires an authenticated user, so the page sits inside the app with the normal chrome.
The page loads the provider’s script and, on success, sends the user to the callback URL:
templates/checkout.twig
Flow 3: Offline or token-based
Methods that settle outside Aikeedo, such as a bank transfer, return aPurchaseToken. The user goes to the receipt page, which shows your instructions, and an administrator marks the order paid later.
OfflinePaymentGatewayInterface so the method is listed with the manual options rather than as a branded button.
The generic checkout buttons don’t do anything special with the token beyond sending the user to the receipt. Only the built-in card form consumes a token client-side.
Flow 4: Charge immediately
If the payment is already complete whenpurchase() runs, for example because you charged a saved payment method, return the provider reference as a plain string. Aikeedo pays and fulfils the order right away, without a callback.
Where the reference lives
completePurchase() must return the provider reference, because it becomes the order’s external ID and, for recurring plans, the subscription’s. There are two ways to get it:
Either way, verify against the provider before returning.
Callback URLs
The callback accepts both
GET and POST, and completePurchase() receives the query parameters merged with the parsed body, so a provider that posts its result works the same as one that redirects.