Skip to main content

Overview

Before proceeding, make sure you’ve read the Online Payments Guide to understand how to create payment requests and handle webhooks. Integrate HitPay payments into your mobile app by opening the checkout URL in an in-app browser. This provides a seamless payment experience while keeping users within your app.

Payment Flow

Implementation

Open the HitPay checkout URL in an in-app browser for the best user experience. Use SFSafariViewController on iOS or Chrome Custom Tabs on Android - they load faster than WebViews and share cookies with the system browser.
import SafariServices

class PaymentViewController: UIViewController, SFSafariViewControllerDelegate {

    func openCheckout(paymentUrl: String) {
        guard let url = URL(string: paymentUrl) else { return }

        let safariVC = SFSafariViewController(url: url)
        safariVC.delegate = self
        present(safariVC, animated: true)
    }

    // Handle redirect back to your app
    func safariViewController(_ controller: SFSafariViewController,
                              initialLoadDidRedirectTo URL: URL) {
        if URL.host == "yourdomain.com" && URL.path == "/payment/success" {
            controller.dismiss(animated: true) {
                self.showPaymentSuccess()
            }
        }
    }

    func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
        // User closed the browser - check payment status via backend
    }
}

Handling the Redirect

After payment, users are redirected to your redirect_url. Set up your redirect URL to:
  1. Close the in-app browser - Detect the redirect and dismiss the browser
  2. Show a confirmation screen - Display a “Payment Processing” or “Success” message
  3. Verify via webhook - Always confirm payment status through webhooks before fulfilling orders
Never rely solely on the redirect to confirm payment. Always wait for the webhook confirmation on your server before marking an order as paid.

Using Embedded QR Codes

In many cases, presenting a webview may not provide the best user experience for your mobile app. This is especially true for QR code-based payment methods where users need to scan a code with their banking app. When to use each approach:
Payment MethodRecommended Approach
Card paymentsIn-app browser
PayNow, QRPH, DuitNow QREmbedded QR codes
For QR code payment methods like PayNow, QRPH, or DuitNow QR, use the Embedded QR Code API to generate a native QR code and display it directly in your app. This provides a smoother experience as users don’t need to leave your app to view the QR code. Build your own payment method selector For the best user experience, consider building your own payment method selection screen:
  1. Display available payment methods to the user
  2. If the user selects a card payment → Use the in-app browser approach
  3. If the user selects a QR code method (PayNow, QRPH, DuitNow QR) → Use the embedded QR code approach
This hybrid approach gives you full control over the UI while leveraging the most appropriate checkout flow for each payment type.

Best Practices

  • Use in-app browsers - Avoid WebViews as they may have security restrictions and don’t share session cookies
  • Handle interruptions - Users may close the browser before completing payment. Always check payment status on your backend
  • Deep linking - Set up proper deep links to handle redirects back to your app
  • Loading states - Show appropriate loading indicators while the payment is being processed
  • Error handling - Handle network errors and payment failures gracefully