> 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/guides/backend-integration.md).

# Backend integration

Use this guide if you are building the backend half of an iOS integration.

The app cannot create a payment. Creating one authenticates with OAuth 2.0 client credentials using your shop client secret, and that secret must stay on your server. The division is:

| Who          | Does what                                                                                               |
| ------------ | ------------------------------------------------------------------------------------------------------- |
| Your backend | Creates the payment, then passes `paymentId`, `verificationKey` and the checkout link to the app.       |
| The SDK      | Presents the checkout page or drives the card session, resolves the payment status, reports one result. |
| Your app     | Puts that result on screen.                                                                             |
| Your backend | Stays authoritative for fulfilment, driven by the platform's notifications.                             |

***

## Create the payment

One call, before the app starts anything:

```
POST {api-host}/egw/v1/payments/cit
Authorization: Bearer {access token}
X-Request-Id: {uuid}
Content-Type: application/json
```

`X-Request-Id` is mandatory and must parse as a UUID. Keep the value: it is how a failed payment is traced later.

```json
{
  "participantId": "your-participant-id",
  "shopAgreementId": "your-shop-agreement-id",
  "channel": "BROWSER",
  "orderNumber": "ORD-1042",
  "instructedAmount": { "currency": "EUR", "amount": "40.12" },
  "customer": {
    "name": "Jane Doe",
    "email": "jane.doe@example.com",
    "phone": "+37129123456"
  },
  "shopRedirectUrl": "myapp://checkout/return",
  "preferredLocale": "en"
}
```

Amounts are decimal strings and currencies are ISO 4217 alpha-3 codes.

`channel` is `BROWSER`. Keep it `BROWSER` for the native card form as well as for hosted checkout.

`shopRedirectUrl` is where the checkout page sends the shopper when it is finished, so point it at your app's return URL. The app must pass the same value as its `returnURL`.

### The response

```json
{
  "paymentId": "019eb631-ee3c-7c4a-90aa-83e13b301e96",
  "orderNumber": "ORD-1042",
  "paymentStatus": "INITIALIZED",
  "instructedAmount": { "currency": "EUR", "amount": "40.12" },
  "environment": "sandbox",
  "participantId": "your-participant-id",
  "shop": { },
  "availablePaymentMethods": [ ],
  "createdAt": "2026-03-04T09:21:44Z",
  "_links": {
    "checkoutRedirect": {
      "href": "https://sandbox-checkout.example.com/en/checkout/019eb631-ee3c-7c4a-90aa-83e13b301e96/9f2c1a7e4b8d"
    }
  }
}
```

***

## Get the verification key

The app needs three values. Two of them are returned directly, and the third comes from the checkout link.

| Value              | Source                                                       |
| ------------------ | ------------------------------------------------------------ |
| `paymentId`        | The `paymentId` field.                                       |
| `checkoutRedirect` | `_links.checkoutRedirect.href`.                              |
| `verificationKey`  | The **last path segment** of `_links.checkoutRedirect.href`. |

The checkout link is built as `{checkoutHost}/{locale}/checkout/{paymentId}/{verificationKey}`, so reading the last segment costs one line and no extra round trip. In the example above the verification key is `9f2c1a7e4b8d`.

Alternatively, call `GET {api-host}/egw/v1/payments/{paymentId}`, which returns `verificationKey` as a field. That costs a second call and does not depend on the shape of a URL.

Pass all three to the app.

### What the verification key is

It is a client-side access credential scoped to one payment. It is not a shop credential, and it authorises the payment-scoped calls the SDK makes on the device.

It is client-visible by design, because the checkout page your app is about to load carries it in its own URL. Two things follow from that: it must not be written to your logs or persisted anywhere it would outlive the payment, and the native card form needs it on the device, because the card session calls go from the app to the checkout API and this is what authorises them.

***

## Choosing a return URL

Your `shopRedirectUrl` and the app's `returnURL` are the same value. You have two options, and the SDK treats them identically.

### Custom scheme

The simplest choice, and it cannot be confused with a real web page. Register it in the app's `Info.plist`:

```xml
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array><string>myapp</string></array>
    </dict>
</array>
```

Then use a URL such as `myapp://checkout/return`.

### Universal link

An `https://` URL you control, such as `https://shop.example.com/pay/done`. Prefer it if you already have universal links configured, or if the same return URL is shared with a web checkout.

{% hint style="info" %}
You are free to append your own query parameters to `shopRedirectUrl`. The platform passes the URL through unchanged, and the SDK ignores query and fragment when it matches. See [return URL matching](broken://pages/3ee6dac002f00ae7971df632083b30b149256dab#how-the-return-url-is-matched).
{% endhint %}

***

## One payment, two ways to pay

There is no separate initiation for the native card form. One payment can be paid through hosted checkout or through your own card form, so an app that offers both makes the same single call and lets the shopper choose.

If card entry is the only method you offer, `shopRedirectUrl` goes unused. The shopper never leaves your app, and a 3-D Secure challenge is presented inside it.

***

## Confirming a payment for the app

The SDK's status lookup is a `GET` on your backend:

```
GET {apiBaseURL}/checkout/api/egw/v1/payments/{paymentId}
```

If your backend serves that shape, set `apiBaseURL` and you are done. If it does not, your app supplies its own lookup instead. See [supplying your own status lookup](/integration/mobile-sdk/ios-sdk/using-the-sdk/handling-the-result.md#supplying-your-own-status-lookup).

{% hint style="warning" %}
⚠️ **Fulfil orders from your backend, never from the app's result.** The device can lose connectivity between a payment completing and your app hearing about it. Drive fulfilment from the notifications the platform sends your backend, and treat the app's result as what to show the shopper.
{% endhint %}


---

# 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/guides/backend-integration.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.
