> For the complete documentation index, see [llms.txt](https://docs.coda.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coda.co/codapay/hosted-payment-page-integration/display-the-hosted-payment-page.md).

# Display the Hosted Payment Page

There are several methods to display the Hosted Payment Page:

* Redirect within the existing page
* Open in a new tab
* Embed within an iFrame
* Display within a webview

You can redirect the customer to the URL returned in the payment request initiation response. Alternatively, use the [Base URL provided below](#details) with appropriate parameters to open the Hosted Payment Page.&#x20;

### Pre-requisite

* You have received a success response from the [payment request initiation](/codapay/hosted-payment-page-integration/initiate-a-payment-request.md).

### Method 1 (Preferred): Using `redirectUrl` returned from payment request initiation to open the Hosted Payment Page

You can use the `redirectUrl` returned in the Successful response of the payment request initiation to open the Hosted Payment Page.

{% hint style="info" %}
If you are within a Native App environment, we recommend opening the `redirectUrl` using an **external browser**, rather than the in-app web-views.
{% endhint %}

{% code overflow="wrap" %}

```json
{
    "initResult": {
        ...
        "redirectUrl": "https://airtime.codapayments.com/airtime/begin?txn_id=7144594637002072212",
        ...
    }
}
```

{% endcode %}

#### Optional: Append optional query parameters to the redirectUrl before opening

Refer to [#query-parameters](#query-parameters "mention") for a list of supported query parameters

***

### Method 2: Using the Base URL & attaching all query parameters to construct the Hosted Payment Page URL

<table><thead><tr><th width="159">Environment</th><th>Base URL</th></tr></thead><tbody><tr><td>Sandbox</td><td><a href="https://sandbox.codapayments.com/airtime/begin?type=3">https://sandbox.codapayments.com/airtime/begin</a></td></tr><tr><td>Production</td><td><a href="https://airtime.codapayments.com/airtime/begin?type=3">https://airtime.codapayments.com/airtime/begin</a></td></tr></tbody></table>

{% hint style="info" %}
If you are within a Native App environment, we recommend opening the `redirectUrl` using an **external browser**, rather than the in-app web-views.
{% endhint %}

#### Query parameters

<table><thead><tr><th width="179">Parameter</th><th width="116">Required</th><th>Description</th></tr></thead><tbody><tr><td>txn_id</td><td>Mandatory</td><td><strong>Mandatory</strong><br>The transaction ID you've collected after initiating the payment</td></tr><tr><td>browser_type</td><td>Optional</td><td><p><strong>Optional</strong></p><p></p><p>If your user is on a mobile device, <code>browser_type=mobile-web</code> needs to be passed to make sure that the payment page is optimised to the device.</p><p></p><p>If any other value or none is passed, the payment page will be optimised for a desktop view.</p></td></tr><tr><td>utm_souce</td><td>Optional</td><td><p>utm_source as it is detected in your page URL.</p><p>For example, utm_souce=google, utm_source=coda</p></td></tr><tr><td>utm_medium</td><td>Optional</td><td><p>utm_medium as it is detected in your page URL.</p><p>For example, utm_medium=banner, utm_medium=email</p></td></tr><tr><td>utm_campaign</td><td>Optional</td><td><p>utm_campaign as it is detected in your page URL.</p><p>For example, utm_campaign=spring_sale, utm_campaign=new_season_launch</p></td></tr><tr><td>utm_content</td><td>Optional</td><td><p>utm_content as it is detected in your page URL.</p><p>For example, utm_content=, utm_content=email</p></td></tr></tbody></table>

### Samples

{% tabs %}
{% tab title="Desktop on Sandbox" %}

```
https://sandbox.codapayments.com/airtime/begin?txn_id=7144594637002072212&utm_source=testing
```

{% endtab %}

{% tab title="Mobile in Production" %}

```
https://airtime.codapayments.com/airtime/begin?txn_id=7144594637002072212&browser_type=mobile-web&utm_source=facebook
```

{% endtab %}
{% endtabs %}

### Unlocking Marketing analytics on payment page

Our payment page supports marketing analytics out-of-the-box. You can pass along UTM parameters from your store's page to the Codapay page. The UTMs will then be available in your payment funnel data analysis & marketing channel attribution analysis.<br>

*\* We recommend that you pass along UTM parameters without any modifications, so that analytics data collected on the hosted payment page can be used together with other analytics data captured on your web page (for instance, data captured using Google Analytics) without any discrepancies.*

#### Example:

The user landed on your page with this UTM tracked URL:

<pre data-overflow="wrap"><code>https://game.webstore.com?<a data-footnote-ref href="#user-content-fn-1">utm_source=google&#x26;utm_medium=cpc&#x26;utm_campaign=123412341234&#x26;utm_content=creative_123</a>
</code></pre>

Then, when the user makes a purchase, you can pass along the UTMs to the Codapay page  URL along with other mandatory URL parameters:

<pre data-overflow="wrap"><code>https://airtime.codapayments.com/airtime/begin?txn_id=7144594637002072212&#x26;browser_type=mobile-web<a data-footnote-ref href="#user-content-fn-2">&#x26;utm_source=google&#x26;utm_medium=cpc&#x26;utm_campaign=123412341234&#x26;utm_content=creative_123</a>
</code></pre>

### Special Considerations for Webviews

#### Handling redirection

Some channels may redirect users to their wallet app. To handle the redirections properly when using Webviews, you will need to use [WebViewClient.shouldOverrideUrlLoading](https://developer.android.com/reference/android/webkit/WebViewClient#shouldOverrideUrlLoading\(android.webkit.WebView,%20java.lang.String\)) using the intents below:

| Regions       | Channel list | Override URL                            | Only support external browser |
| ------------- | ------------ | --------------------------------------- | ----------------------------- |
| Brazil        | PicPay       | picpay://                               |                               |
| Brazil        | AmeDigital   | amedigital://                           |                               |
| Indonesia     | GO-PAY       | gojek://                                |                               |
| Indonesia     | Shopee Pay   | <p>shopeeid:// &<br>shopeepayid://</p>  |                               |
| Indonesia     | Dana         | danaid:// & market://details?id=id.dana |                               |
| Malaysia      | GrabPay      | grab://                                 |                               |
| Malaysia      | Shopee Pay   | shopeepaymy://                          |                               |
| Malaysia      | Maxis        | sms:32083                               |                               |
| Malaysia      | -            | -                                       | U Mobile                      |
| Singapore     | GrabPay      | grab://                                 |                               |
| Philippines   | GrabPay      | grab://                                 |                               |
| Philippines   | GCash        | gcash://                                |                               |
| Thailand      | Shopee Pay   | intent://                               |                               |
| Taiwan        | Line Pay     | intent://                               |                               |
| Myanmar       | KBZPay       | intent://                               |                               |
| United States | Cash App     | cashme://                               |                               |
| Vietnam       | MoMo         | momo://                                 |                               |
| All countries | -            | -                                       | Google Pay/Apple Pay          |

#### Common Webview Pitfalls and Tips

<details>

<summary>Android WebView Configuration</summary>

When using Android's WebView, configure `WebViewClient` as follows:

1. **Override the `onCreateWindow` Method:**

```java
override fun onCreateWindow(view: WebView, dialog: Boolean, userGesture: Boolean, resultMsg: Message): Boolean {
    val newWebView = WebView(view.context)
    view.webViewClient?.let { newWebView.webViewClient = it }
    val webSettings = newWebView.settings
    setWebSettings(webSettings)
    (resultMsg.obj as WebView.WebViewTransport).webView = newWebView
    resultMsg.sendToTarget()
    return true
}
```

2. **Set WebView Settings:**

```java
fun setWebSettings(webSettings: WebSettings) {
    webSettings.javaScriptEnabled = true
    webSettings.setSupportMultipleWindows(true)
    webSettings.domStorageEnabled = true
    webSettings.loadsImagesAutomatically = true
    webSettings.mediaPlaybackRequiresUserGesture = false
    webSettings.cacheMode = WebSettings.LOAD_DEFAULT
}
```

</details>

<details>

<summary>ERR_UNKNOWN_URL_SCHEME</summary>

**Root Cause**

The webview only recognizes standard URL schemes like `http` and `https`. Custom schemes, such as `weixin://` and `qunaraphone://`, are not recognized by the webview, leading to the error `ERR_UNKNOWN_URL_SCHEME`. This error indicates that the webview cannot handle the custom scheme provided by the payment channel.

**Solution**

To handle custom URL schemes, you need to override the `shouldOverrideUrlLoading` method in `WebViewClient`. This method allows you to intercept and manage URL loading behavior in Webview, ensuring that custom schemes are properly handled.

Steps to implement the solution:

1. Implement the `shouldOverrideUrlLoading(WebView view, String url)` method in your `WebViewClient` class.
2. Configure the method to intercept URLs and handle custom schemes:
   * **Return `true`**: When the URL uses a custom scheme that needs special handling. This indicates that Webview should not handle the URL and allows you to process it as needed.
   * **Return `false`**: For standard schemes (`http`, `https`), allowing Webview to load the URL as usual.

Example implementation:

```kotlin
kotlinCopy codeoverride fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
    if (url != null && url.startsWith("customscheme://")) {
        // Handle custom scheme
        return true
    }
    return false // Default behavior for standard schemes
}
```

By implementing this method, you can ensure that custom URL schemes are properly redirected or handled according to your application's requirements, preventing the `ERR_UNKNOWN_URL_SCHEME` error.

</details>

<details>

<summary>Screen Rotation Issues</summary>

Screen rotation can cause the webview pages to refresh and display errors.

**Solution**

Add the following to your `AndroidManifest.xml` to prevent activity restart on screen orientation change:

```xml
xmlCopy code<activity
    android:configChanges="orientation|screenSize|keyboardHidden"/>
```

This ensures that the activity remains stable during screen rotation.

</details>

<details>

<summary>iOS Webview (about:blank)</summary>

Implement the `WKUIDelegate` delegate and set it to `_webview.uiDelegate`. Then implement:

```java
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
  if (!navigationAction.targetFrame.isMainFrame) {
    [webView loadRequest:navigationAction.request];
  }

  return nil;
}
```

</details>

<details>

<summary>iOS Webview (Capture redirect URL)</summary>

WKWebView is located at the iOS system level and cannot be directly accessed or modified via API. Due to the strict limitations of iOS, we recommend:

```java
webView(_:createWebViewWith:for:windowFeatures adjust
swift

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? 
{ if navigationAction.targetFrame == nil { webView.load(navigationAction.request) } return nil }
{ if navigationAction.targetFrame == nil { webView.load(navigationAction.request) } return nil }
```

</details>

[^1]: These are UTM parameters added by Marketers to identify where users are coming to your page from.

[^2]: Passing these UTM parameters along to Codapay page allows us to map the transaction to the marketing campaigns that brought them to the page.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.coda.co/codapay/hosted-payment-page-integration/display-the-hosted-payment-page.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
