> For the complete documentation index, see [llms.txt](https://docs.ecommerce.seb.ee/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ecommerce.seb.ee/integration/mobile-sdk/ios-sdk/using-the-sdk/hosted-checkout.md).

# Hosted checkout

Present the hosted checkout page, match your return URL, and preselect a payment method.

Use this guide if you want the shopper to pay on the hosted checkout page, with every payment method the platform offers and no card data inside your app.

The page runs in a [`WKWebView`](https://developer.apple.com/documentation/webkit/wkwebview) the SDK presents modally. Card, Pay by Bank, Click to Pay, the wallets and EMV® 3-D Secure all work there without any further integration on your side.

***

## Configure

Hosted checkout needs one URL: the backend the SDK asks for the payment status once the shopper is done.

```swift
let configuration = Configuration(
    apiBaseURL: URL(string: "https://your-backend.example.com"),
    environment: .sandbox
)

let paymentKit = PaymentKit(configuration: configuration)
```

`apiBaseURL` is your own backend, because that is the party with a reason to own payment state. The SDK appends `/checkout/api/egw/v1/payments/{paymentId}` to it. If your backend exposes a different path shape, leave `apiBaseURL` as `nil` and supply your own lookup instead: see [Handling the result](/integration/mobile-sdk/ios-sdk/using-the-sdk/handling-the-result.md).

Hold one `PaymentKit` for the life of your checkout screen, or create one per payment. Either is fine. One instance runs one payment at a time. Full property list in [Configuration](broken://pages/f53963955478c17a845bd68be40c141079362690).

***

## Build the request

```swift
let request = PaymentRequest(
    paymentId: payment.paymentId,
    verificationKey: payment.verificationKey,
    checkoutURL: payment.checkoutRedirect,
    returnURL: URL(string: "myapp://checkout/return")!
)
```

`returnURL` must be the same value your backend sent as `shopRedirectUrl` when it created the payment.

The SDK validates the request before presenting anything, so an empty `paymentId`, an empty `verificationKey`, a checkout URL that is not `http`/`https`, or a return URL with no scheme all come back through your normal callback rather than showing an empty web view.

### Preselecting a payment method

By default the checkout page opens on its method chooser. To open straight onto one method:

```swift
request.preferredMethod = PaymentRequest.MethodHint.card
```

| Constant                               | Value            |
| -------------------------------------- | ---------------- |
| `PaymentRequest.MethodHint.card`       | `"card"`         |
| `PaymentRequest.MethodHint.bank`       | `"bank"`         |
| `PaymentRequest.MethodHint.clickToPay` | `"click-to-pay"` |

An unrecognised value is ignored rather than appended, so a typo shows the method chooser instead of breaking the checkout URL.

***

## Present it

```swift
paymentKit.startPayment(request, from: self) { result in
    switch result.outcome {
    case .succeeded:  self.showReceipt(reference: result.orderNumber ?? result.paymentId)
    case .failed:     self.showFailure(message: result.error?.localizedDescription)
    case .cancelled:  break
    case .unresolved: self.confirmWithBackend(paymentId: result.paymentId)
    }
}
```

`from:` is the view controller the SDK presents over. It must be on screen and must not already be presenting something else.

The SDK dismisses its own interface before calling you back, so presenting your receipt screen from inside the callback works. See [Handling the result](/integration/mobile-sdk/ios-sdk/using-the-sdk/handling-the-result.md) for the full contract.

An `EGWPaymentDelegate`-based overload is available as an alternative to the completion block. See [Objective-C and SwiftUI](/integration/mobile-sdk/ios-sdk/using-the-sdk/objective-c-and-swiftui.md).

***

## How the return URL is matched

The SDK stops the flow when the shopper's browser reaches your return URL. Matching compares **scheme, host, and path prefix by whole segments**, and ignores query and fragment.

A return URL of `https://shop.example.com/pay/done` matches:

* `https://shop.example.com/pay/done`
* `https://shop.example.com/pay/done?order=1042#thanks`
* `https://shop.example.com/pay/done/thanks`

and does not match `https://shop.example.com/pay/done-not-really`, or the same path on a different host.

Query is ignored because you are free to append your own parameters to `shopRedirectUrl`, and the platform passes that URL through unchanged.

{% hint style="warning" %}
**Reaching the return URL does not mean the payment succeeded.** No status is appended to it. That is why the SDK looks the status up afterwards, and why your app must not read an outcome out of the URL itself.
{% endhint %}

### Custom schemes and universal links

Both work, and both behave identically as far as the SDK is concerned.

A custom scheme such as `myapp://checkout/return` is the simplest choice and cannot be confused with a real web page. A universal link is worth preferring if you already have one set up, or if the same return URL is shared with a web checkout. [Backend integration](/integration/mobile-sdk/ios-sdk/guides/backend-integration.md) covers the setup for each.

### Handoff to other apps

Navigations to non-web schemes are handed to the system rather than loaded in the web view. This is what lets a Pay by Bank flow open the shopper's banking app for strong customer authentication and return to your app afterwards.

***

## Timeouts

`requestTimeout` bounds the SDK's own API calls. Neither web view is timed out: a shopper reading a bank's confirmation screen is not a stalled request.

***

## Next steps

* [Handling the result](/integration/mobile-sdk/ios-sdk/using-the-sdk/handling-the-result.md)
* [Error handling](/integration/mobile-sdk/ios-sdk/guides/error-handling.md)
* [Native card form](/integration/mobile-sdk/ios-sdk/using-the-sdk/native-card-form.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ecommerce.seb.ee/integration/mobile-sdk/ios-sdk/using-the-sdk/hosted-checkout.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
